Compare commits
47 Commits
jebbatime
...
zephyr-reb
Author | SHA1 | Date |
---|---|---|
Daniel Thompson | 676e97cbe5 | |
Daniel Thompson | 29eccb1007 | |
Daniel Thompson | bba5d67ced | |
Daniel Thompson | eddd31ff34 | |
Daniel Thompson | 9ef2ec9110 | |
Paul Sokolovsky | 7b562a2be8 | |
Paul Sokolovsky | f756c04a63 | |
Paul Sokolovsky | c1af9588d1 | |
Paul Sokolovsky | 4de1683601 | |
Daniel Thompson | 59a6b29748 | |
Daniel Thompson | adf833d8a1 | |
Daniel Thompson | a2be942dc2 | |
Daniel Thompson | 9edf72ecae | |
Paul Sokolovsky | 66cac184af | |
Paul Sokolovsky | 75eb7ec066 | |
Paul Sokolovsky | 79deb6cf49 | |
Paul Sokolovsky | fa1b9593ed | |
Paul Sokolovsky | a39fe7d449 | |
Paul Sokolovsky | 718b896f48 | |
Paul Sokolovsky | 5269f23b2c | |
Paul Sokolovsky | 2743eb105a | |
Paul Sokolovsky | 858d859d79 | |
Paul Sokolovsky | ce7480d282 | |
Paul Sokolovsky | c5b33851d7 | |
Paul Sokolovsky | 9290942f3a | |
Paul Sokolovsky | d3ef82ec16 | |
Paul Sokolovsky | 307612600d | |
Paul Sokolovsky | e4a167d42a | |
Paul Sokolovsky | 8661fc288b | |
Paul Sokolovsky | 3893a04f48 | |
Paul Sokolovsky | 2d387aa794 | |
Paul Sokolovsky | 1e8605882a | |
Paul Sokolovsky | b7ac314861 | |
Paul Sokolovsky | 545b5a21c6 | |
Paul Sokolovsky | 0b552e7f06 | |
Paul Sokolovsky | ed312b0575 | |
Paul Sokolovsky | 6ea9c13fee | |
Paul Sokolovsky | 8527d4803d | |
Paul Sokolovsky | 4f9ce589f8 | |
Paul Sokolovsky | 8f68768a34 | |
Paul Sokolovsky | 7ca39a89ef | |
Paul Sokolovsky | c0f192f13e | |
Paul Sokolovsky | 0882e0e997 | |
Paul Sokolovsky | 26ffe8587b | |
Paul Sokolovsky | 84b92e6f28 | |
Paul Sokolovsky | ec252ff8f3 | |
Paul Sokolovsky | 3c4fa6a080 |
|
@ -7,20 +7,25 @@
|
||||||
*.bat text eol=crlf
|
*.bat text eol=crlf
|
||||||
|
|
||||||
# These are binary so should never be modified by git.
|
# These are binary so should never be modified by git.
|
||||||
*.a binary
|
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
*.dxf binary
|
*.dxf binary
|
||||||
*.mpy binary
|
|
||||||
|
|
||||||
# These should also not be modified by git.
|
# These should also not be modified by git.
|
||||||
tests/basics/string_cr_conversion.py -text
|
tests/basics/string_cr_conversion.py -text
|
||||||
tests/basics/string_crlf_conversion.py -text
|
tests/basics/string_crlf_conversion.py -text
|
||||||
ports/stm32/pybcdc.inf_template -text
|
stmhal/startup_stm32f40xx.s -text
|
||||||
ports/stm32/usbhost/** -text
|
stmhal/pybcdc.inf_template -text
|
||||||
ports/cc3200/hal/aes.c -text
|
stmhal/usbd_* -text
|
||||||
ports/cc3200/hal/aes.h -text
|
stmhal/boards/*/stm32f4xx_hal_conf.h -text
|
||||||
ports/cc3200/hal/des.c -text
|
stmhal/cmsis/** -text
|
||||||
ports/cc3200/hal/i2s.c -text
|
stmhal/hal/** -text
|
||||||
ports/cc3200/hal/i2s.h -text
|
stmhal/usbdev/** -text
|
||||||
ports/cc3200/version.h -text
|
stmhal/usbhost/** -text
|
||||||
|
cc3200/hal/aes.c -text
|
||||||
|
cc3200/hal/aes.h -text
|
||||||
|
cc3200/hal/des.c -text
|
||||||
|
cc3200/hal/i2s.c -text
|
||||||
|
cc3200/hal/i2s.h -text
|
||||||
|
cc3200/version.h -text
|
||||||
|
lib/fatfs/** -text
|
||||||
|
|
|
@ -9,22 +9,20 @@
|
||||||
*.dis
|
*.dis
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
# Packages
|
# Packages
|
||||||
############
|
############
|
||||||
|
|
||||||
# Logs and Databases
|
# Logs and Databases
|
||||||
######################
|
######################
|
||||||
*.log
|
*.log
|
||||||
cscope.out
|
|
||||||
|
|
||||||
# VIM Swap Files
|
# VIM Swap Files
|
||||||
######################
|
######################
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
# Build directories
|
# Build directory
|
||||||
######################
|
######################
|
||||||
build/
|
build/
|
||||||
build-*/
|
|
||||||
|
|
||||||
# Test failure outputs
|
# Test failure outputs
|
||||||
######################
|
######################
|
||||||
|
@ -40,7 +38,3 @@ __pycache__/
|
||||||
######################
|
######################
|
||||||
GNUmakefile
|
GNUmakefile
|
||||||
user.props
|
user.props
|
||||||
|
|
||||||
# Generated rst files
|
|
||||||
######################
|
|
||||||
genrst/
|
|
||||||
|
|
|
@ -1,32 +1,13 @@
|
||||||
[submodule "lib/axtls"]
|
[submodule "lib/axtls"]
|
||||||
path = lib/axtls
|
path = lib/axtls
|
||||||
url = https://mirrors.spacecruft.org/pfalcon/axtls
|
url = https://github.com/pfalcon/axtls
|
||||||
branch = micropython
|
branch = micropython
|
||||||
[submodule "lib/libffi"]
|
[submodule "lib/libffi"]
|
||||||
path = lib/libffi
|
path = lib/libffi
|
||||||
url = https://mirrors.spacecruft.org/atgreen/libffi
|
url = https://github.com/atgreen/libffi
|
||||||
[submodule "lib/lwip"]
|
[submodule "lib/lwip"]
|
||||||
path = lib/lwip
|
path = lib/lwip
|
||||||
url = https://mirrors.spacecruft.org/savannah/lwip
|
url = http://git.savannah.gnu.org/r/lwip.git
|
||||||
[submodule "lib/berkeley-db-1.xx"]
|
[submodule "lib/berkeley-db-1.xx"]
|
||||||
path = lib/berkeley-db-1.xx
|
path = lib/berkeley-db-1.xx
|
||||||
url = https://mirrors.spacecruft.org/pfalcon/berkeley-db-1.xx
|
url = https://github.com/pfalcon/berkeley-db-1.xx
|
||||||
[submodule "lib/stm32lib"]
|
|
||||||
path = lib/stm32lib
|
|
||||||
url = https://mirrors.spacecruft.org/micropython/stm32lib
|
|
||||||
branch = work-F4-1.13.1+F7-1.5.0+L4-1.3.0
|
|
||||||
[submodule "lib/nrfx"]
|
|
||||||
path = lib/nrfx
|
|
||||||
url = https://mirrors.spacecruft.org/NordicSemiconductor/nrfx.git
|
|
||||||
[submodule "lib/mbedtls"]
|
|
||||||
path = lib/mbedtls
|
|
||||||
url = https://mirrors.spacecruft.org/ARMmbed/mbedtls.git
|
|
||||||
[submodule "lib/asf4"]
|
|
||||||
path = lib/asf4
|
|
||||||
url = https://mirrors.spacecruft.org/adafruit/asf4
|
|
||||||
[submodule "lib/tinyusb"]
|
|
||||||
path = lib/tinyusb
|
|
||||||
url = https://mirrors.spacecruft.org/hathach/tinyusb
|
|
||||||
[submodule "lib/mynewt-nimble"]
|
|
||||||
path = lib/mynewt-nimble
|
|
||||||
url = https://mirrors.spacecruft.org/apache/mynewt-nimble.git
|
|
||||||
|
|
306
.travis.yml
306
.travis.yml
|
@ -1,265 +1,57 @@
|
||||||
# global options
|
sudo: required
|
||||||
dist: xenial
|
dist: trusty
|
||||||
language:
|
language: c
|
||||||
- c
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- "${HOME}/persist"
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- MAKEOPTS="-j4"
|
|
||||||
git:
|
|
||||||
submodules: false
|
|
||||||
|
|
||||||
# define the successive stages
|
before_script:
|
||||||
stages:
|
# Extra CPython versions
|
||||||
- name: test
|
# - sudo add-apt-repository -y ppa:fkrull/deadsnakes
|
||||||
|
# Extra gcc versions
|
||||||
|
# - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||||
|
- sudo add-apt-repository -y ppa:terry.guo/gcc-arm-embedded
|
||||||
|
- sudo dpkg --add-architecture i386
|
||||||
|
- sudo apt-get update -qq || true
|
||||||
|
- sudo apt-get install -y python3 gcc-multilib pkg-config libffi-dev libffi-dev:i386 qemu-system gcc-mingw-w64
|
||||||
|
- sudo apt-get install -y --force-yes gcc-arm-none-eabi
|
||||||
|
# For teensy build
|
||||||
|
- sudo apt-get install realpath
|
||||||
|
# For coverage testing
|
||||||
|
- sudo pip install cpp-coveralls
|
||||||
|
- gcc --version
|
||||||
|
- arm-none-eabi-gcc --version
|
||||||
|
- python3 --version
|
||||||
|
|
||||||
# define the jobs for the stages
|
script:
|
||||||
# order of the jobs has longest running first to optimise total time
|
- make -C mpy-cross
|
||||||
jobs:
|
- make -C minimal test
|
||||||
include:
|
- make -C unix deplibs
|
||||||
# stm32 port
|
- make -C unix
|
||||||
- stage: test
|
- make -C unix nanbox
|
||||||
env: NAME="stm32 port build"
|
- make -C bare-arm
|
||||||
install:
|
- make -C qemu-arm test
|
||||||
# need newer gcc version for Cortex-M7 support
|
- make -C stmhal
|
||||||
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
|
- make -C stmhal -B MICROPY_PY_WIZNET5K=1 MICROPY_PY_CC3K=1
|
||||||
- sudo apt-get update -qq || true
|
- make -C stmhal BOARD=STM32F4DISC
|
||||||
- sudo apt-get install gcc-arm-embedded
|
- make -C teensy
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
- make -C cc3200 BTARGET=application BTYPE=release
|
||||||
- arm-none-eabi-gcc --version
|
- make -C cc3200 BTARGET=bootloader BTYPE=release
|
||||||
script:
|
- make -C windows CROSS_COMPILE=i686-w64-mingw32-
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_WIZNET5K=5200 MICROPY_PY_CC3K=1
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1'
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=B_L072Z_LRWAN1
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=STM32L476DISC
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55
|
|
||||||
- make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6
|
|
||||||
|
|
||||||
# qemu-arm port
|
# run tests without coverage info
|
||||||
- stage: test
|
#- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests)
|
||||||
env: NAME="qemu-arm port build and tests"
|
#- (cd tests && MICROPY_CPYTHON3=python3.4 ./run-tests --emit native)
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-arm-none-eabi
|
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
|
||||||
- sudo apt-get install qemu-system
|
|
||||||
- arm-none-eabi-gcc --version
|
|
||||||
- qemu-system-arm --version
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test
|
|
||||||
after_failure:
|
|
||||||
- grep "FAIL" ports/qemu-arm/build/console.out
|
|
||||||
|
|
||||||
# unix coverage
|
# run tests with coverage info
|
||||||
- stage: test
|
- make -C unix coverage
|
||||||
env: NAME="unix coverage build and tests"
|
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests)
|
||||||
install:
|
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests -d thread)
|
||||||
- sudo apt-get install python3-pip
|
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests --emit native)
|
||||||
- sudo pip install cpp-coveralls
|
- (cd tests && MICROPY_CPYTHON3=python3.4 MICROPY_MICROPYTHON=../unix/micropython_coverage ./run-tests --via-mpy -d basics)
|
||||||
- sudo pip3 install setuptools
|
|
||||||
- sudo pip3 install pyelftools
|
|
||||||
- gcc --version
|
|
||||||
- python3 --version
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/unix submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/unix deplibs
|
|
||||||
- make ${MAKEOPTS} -C ports/unix coverage
|
|
||||||
# run the main test suite
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests)
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests -d thread)
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --emit native)
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy -d basics float micropython)
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_coverage ./run-tests --via-mpy --emit native -d basics float micropython)
|
|
||||||
# test when input script comes from stdin
|
|
||||||
- cat tests/basics/0prelim.py | ports/unix/micropython_coverage | grep -q 'abc'
|
|
||||||
# test building native mpy modules
|
|
||||||
- make -C examples/natmod/features1 ARCH=x64
|
|
||||||
- make -C examples/natmod/features2 ARCH=x64
|
|
||||||
- make -C examples/natmod/btree ARCH=x64
|
|
||||||
- make -C examples/natmod/framebuf ARCH=x64
|
|
||||||
- make -C examples/natmod/uheapq ARCH=x64
|
|
||||||
- make -C examples/natmod/urandom ARCH=x64
|
|
||||||
- make -C examples/natmod/ure ARCH=x64
|
|
||||||
- make -C examples/natmod/uzlib ARCH=x64
|
|
||||||
# test importing .mpy generated by mpy_ld.py
|
|
||||||
- MICROPYPATH=examples/natmod/features2 ./ports/unix/micropython_coverage -m features2
|
|
||||||
- (cd tests && ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py)
|
|
||||||
# run coveralls coverage analysis (try to, even if some builds/tests failed)
|
|
||||||
- (cd ports/unix && coveralls --root ../.. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod)
|
|
||||||
after_failure:
|
|
||||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
|
||||||
|
|
||||||
# standard unix port
|
after_success:
|
||||||
- stage: test
|
- (cd unix && coveralls --root .. --build-root . --gcov $(which gcov) --gcov-options '\-o build-coverage/' --include py --include extmod)
|
||||||
env: NAME="unix port build and tests"
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/unix submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/unix deplibs
|
|
||||||
- make ${MAKEOPTS} -C ports/unix
|
|
||||||
- make ${MAKEOPTS} -C ports/unix test
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython ./run-perfbench.py 1000 1000)
|
|
||||||
|
|
||||||
# unix nanbox (and using Python 2 to check it can run the build scripts)
|
after_failure:
|
||||||
- stage: test
|
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
||||||
env: NAME="unix nanbox port build and tests"
|
- (grep "FAIL" qemu-arm/build/console.out)
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-multilib libffi-dev:i386
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross PYTHON=python2
|
|
||||||
- make ${MAKEOPTS} -C ports/unix submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/unix PYTHON=python2 deplibs
|
|
||||||
- make ${MAKEOPTS} -C ports/unix PYTHON=python2 nanbox
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_nanbox ./run-tests)
|
|
||||||
|
|
||||||
# unix stackless
|
|
||||||
- stage: test
|
|
||||||
env: NAME="unix stackless port build and tests with clang"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install clang
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross CC=clang
|
|
||||||
- make ${MAKEOPTS} -C ports/unix submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1"
|
|
||||||
- make ${MAKEOPTS} -C ports/unix CC=clang test
|
|
||||||
|
|
||||||
# unix with sys.settrace
|
|
||||||
- stage: test
|
|
||||||
env: NAME="unix port with sys.settrace build and tests"
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_PY_SYS_SETTRACE=1" test
|
|
||||||
- make ${MAKEOPTS} -C ports/unix clean
|
|
||||||
- make ${MAKEOPTS} -C ports/unix MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 MICROPY_PY_USSL=0 CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" test
|
|
||||||
after_failure:
|
|
||||||
- (cd tests && for exp in *.exp; do testbase=$(basename $exp .exp); echo -e "\nFAILURE $testbase"; diff -u $testbase.exp $testbase.out; done)
|
|
||||||
|
|
||||||
# minimal unix port with tests
|
|
||||||
- stage: test
|
|
||||||
env: NAME="minimal unix port build and tests"
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/unix minimal
|
|
||||||
- (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython_minimal ./run-tests -e exception_chain -e self_type_check -e subclass_native_init -d basics)
|
|
||||||
|
|
||||||
# windows port via mingw
|
|
||||||
- stage: test
|
|
||||||
env: NAME="windows port build via mingw"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-mingw-w64
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32-
|
|
||||||
|
|
||||||
# esp32 port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="esp32 port build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install python3-pip
|
|
||||||
- sudo pip3 install 'pyparsing<2.4'
|
|
||||||
- wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz
|
|
||||||
- zcat xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz | tar x
|
|
||||||
- export PATH=$(pwd)/xtensa-esp32-elf/bin:$PATH
|
|
||||||
- git clone https://github.com/espressif/esp-idf.git
|
|
||||||
- export IDF_PATH=$(pwd)/esp-idf
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
# IDF v3 build
|
|
||||||
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V3 :=" ports/esp32/Makefile | cut -d " " -f 3)
|
|
||||||
- git -C esp-idf submodule update --init components/json/cJSON components/esp32/lib components/esptool_py/esptool components/expat/expat components/lwip/lwip components/mbedtls/mbedtls components/micro-ecc/micro-ecc components/nghttp/nghttp2
|
|
||||||
- make ${MAKEOPTS} -C ports/esp32 submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/esp32
|
|
||||||
# clean
|
|
||||||
- git -C esp-idf clean -f -f -d components/json/cJSON components/esp32/lib components/expat/expat components/micro-ecc/micro-ecc components/nghttp/nghttp2
|
|
||||||
- make ${MAKEOPTS} -C ports/esp32 clean
|
|
||||||
# IDF v4 build
|
|
||||||
- git -C esp-idf checkout $(grep "ESPIDF_SUPHASH_V4 :=" ports/esp32/Makefile | cut -d " " -f 3)
|
|
||||||
- git -C esp-idf submodule update --init components/bt/controller/lib components/bt/host/nimble/nimble components/esp_wifi/lib_esp32 components/esptool_py/esptool components/lwip/lwip components/mbedtls/mbedtls
|
|
||||||
- make ${MAKEOPTS} -C ports/esp32 submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/esp32
|
|
||||||
|
|
||||||
# esp8266 port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="esp8266 port build"
|
|
||||||
install:
|
|
||||||
- wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz
|
|
||||||
- zcat xtensa-lx106-elf-standalone.tar.gz | tar x
|
|
||||||
- export PATH=$(pwd)/xtensa-lx106-elf/bin:$PATH
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C mpy-cross
|
|
||||||
- make ${MAKEOPTS} -C ports/esp8266 submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/esp8266
|
|
||||||
- make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_512K
|
|
||||||
|
|
||||||
# nrf port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="nrf port build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-arm-none-eabi
|
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
|
||||||
- arm-none-eabi-gcc --version
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/nrf submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/nrf
|
|
||||||
|
|
||||||
# bare-arm and minimal ports
|
|
||||||
- stage: test
|
|
||||||
env: NAME="bare-arm and minimal ports build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-arm-none-eabi
|
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
|
||||||
- arm-none-eabi-gcc --version
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/bare-arm
|
|
||||||
- make ${MAKEOPTS} -C ports/minimal CROSS=1 build/firmware.bin
|
|
||||||
- ls -l ports/minimal/build/firmware.bin
|
|
||||||
- tools/check_code_size.sh
|
|
||||||
- mkdir -p ${HOME}/persist
|
|
||||||
# Save new firmware for reference, but only if building a main branch, not a pull request
|
|
||||||
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then cp ports/minimal/build/firmware.bin ${HOME}/persist/; fi'
|
|
||||||
|
|
||||||
# cc3200 port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="cc3200 port build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-arm-none-eabi
|
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/cc3200 BTARGET=application BTYPE=release
|
|
||||||
- make ${MAKEOPTS} -C ports/cc3200 BTARGET=bootloader BTYPE=release
|
|
||||||
|
|
||||||
# samd port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="samd port build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-arm-none-eabi
|
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/samd submodules
|
|
||||||
- make ${MAKEOPTS} -C ports/samd
|
|
||||||
|
|
||||||
# teensy port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="teensy port build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-arm-none-eabi
|
|
||||||
- sudo apt-get install libnewlib-arm-none-eabi
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/teensy
|
|
||||||
|
|
||||||
# powerpc port
|
|
||||||
- stage: test
|
|
||||||
env: NAME="powerpc port build"
|
|
||||||
install:
|
|
||||||
- sudo apt-get install gcc-powerpc64le-linux-gnu
|
|
||||||
- sudo apt-get install libc6-dev-ppc64el-cross
|
|
||||||
script:
|
|
||||||
- make ${MAKEOPTS} -C ports/powerpc CROSS_COMPILE=powerpc64le-linux-gnu-
|
|
||||||
|
|
|
@ -762,6 +762,7 @@ today. The names appear in order of pledging.
|
||||||
1642 Udine
|
1642 Udine
|
||||||
1643 Simon Critchley
|
1643 Simon Critchley
|
||||||
1644 Sven Haiges, Germany
|
1644 Sven Haiges, Germany
|
||||||
|
1645 Yi Qing Sim
|
||||||
1646 "silicium" ("silicium_one", if "silicium" is busy)
|
1646 "silicium" ("silicium_one", if "silicium" is busy)
|
||||||
1648 Andy O'Malia, @andyomalia
|
1648 Andy O'Malia, @andyomalia
|
||||||
1650 RedCamelApps.com
|
1650 RedCamelApps.com
|
||||||
|
@ -1447,7 +1448,7 @@ indicating that they also supported the first campaign.
|
||||||
* 902 B Stevens
|
* 902 B Stevens
|
||||||
903 Cptnslick, US
|
903 Cptnslick, US
|
||||||
904 janlj@me.com
|
904 janlj@me.com
|
||||||
905 Fabricio Biazzotto
|
905 SĂŁo Caetano do Sul, SP, Brazil
|
||||||
906 Lenz Hirsch
|
906 Lenz Hirsch
|
||||||
907 SerSher, RU
|
907 SerSher, RU
|
||||||
908 Florian, DE
|
908 Florian, DE
|
||||||
|
|
|
@ -24,28 +24,7 @@ a change in a detail, if needed. Any change beyond 5 lines would likely
|
||||||
require such detailed description.
|
require such detailed description.
|
||||||
|
|
||||||
To get good practical examples of good commits and their messages, browse
|
To get good practical examples of good commits and their messages, browse
|
||||||
the `git log` of the project.
|
thry the `git log` of the project.
|
||||||
|
|
||||||
MicroPython doesn't require explicit sign-off for patches ("Signed-off-by"
|
|
||||||
lines and similar). Instead, the commit message, and your name and email
|
|
||||||
address on it construes your sign-off of the following:
|
|
||||||
|
|
||||||
* That you wrote the change yourself, or took it from a project with
|
|
||||||
a compatible license (in the latter case the commit message, and possibly
|
|
||||||
source code should provide reference where the implementation was taken
|
|
||||||
from and give credit to the original author, as required by the license).
|
|
||||||
* That you are allowed to release these changes to an open-source project
|
|
||||||
(for example, changes done during paid work for a third party may require
|
|
||||||
explicit approval from that third party).
|
|
||||||
* That you (or your employer) agree to release the changes under
|
|
||||||
MicroPython's license, which is the MIT license. Note that you retain
|
|
||||||
copyright for your changes (for smaller changes, the commit message
|
|
||||||
conveys your copyright; if you make significant changes to a particular
|
|
||||||
source module, you're welcome to add your name to the file header).
|
|
||||||
* Your signature for all of the above, which is the 'Author' line in
|
|
||||||
the commit message, and which should include your full real name and
|
|
||||||
a valid and active email address by which you can be contacted in the
|
|
||||||
foreseeable future.
|
|
||||||
|
|
||||||
Python code conventions
|
Python code conventions
|
||||||
=======================
|
=======================
|
||||||
|
@ -73,7 +52,7 @@ White space:
|
||||||
keyword and the opening parenthesis.
|
keyword and the opening parenthesis.
|
||||||
- Put 1 space after a comma, and 1 space around operators.
|
- Put 1 space after a comma, and 1 space around operators.
|
||||||
|
|
||||||
Braces:
|
Braces:
|
||||||
- Use braces for all blocks, even no-line and single-line pieces of
|
- Use braces for all blocks, even no-line and single-line pieces of
|
||||||
code.
|
code.
|
||||||
- Put opening braces on the end of the line it belongs to, not on
|
- Put opening braces on the end of the line it belongs to, not on
|
||||||
|
@ -135,76 +114,3 @@ Type declarations:
|
||||||
int member;
|
int member;
|
||||||
void *data;
|
void *data;
|
||||||
} my_struct_t;
|
} my_struct_t;
|
||||||
|
|
||||||
Documentation conventions
|
|
||||||
=========================
|
|
||||||
|
|
||||||
MicroPython generally follows CPython in documentation process and
|
|
||||||
conventions. reStructuredText syntax is used for the documention.
|
|
||||||
|
|
||||||
Specific conventions/suggestions:
|
|
||||||
|
|
||||||
* Use `*` markup to refer to arguments of a function, e.g.:
|
|
||||||
|
|
||||||
```
|
|
||||||
.. method:: poll.unregister(obj)
|
|
||||||
|
|
||||||
Unregister *obj* from polling.
|
|
||||||
```
|
|
||||||
|
|
||||||
* Use following syntax for cross-references/cross-links:
|
|
||||||
|
|
||||||
```
|
|
||||||
:func:`foo` - function foo in current module
|
|
||||||
:func:`module1.foo` - function foo in module "module1"
|
|
||||||
(similarly for other referent types)
|
|
||||||
:class:`Foo` - class Foo
|
|
||||||
:meth:`Class.method1` - method1 in Class
|
|
||||||
:meth:`~Class.method1` - method1 in Class, but rendered just as "method1()",
|
|
||||||
not "Class.method1()"
|
|
||||||
:meth:`title <method1>` - reference method1, but render as "title" (use only
|
|
||||||
if really needed)
|
|
||||||
:mod:`module1` - module module1
|
|
||||||
|
|
||||||
`symbol` - generic xref syntax which can replace any of the above in case
|
|
||||||
the xref is unambiguous. If there's ambiguity, there will be a warning
|
|
||||||
during docs generation, which need to be fixed using one of the syntaxes
|
|
||||||
above
|
|
||||||
```
|
|
||||||
|
|
||||||
* Cross-referencing arbitrary locations
|
|
||||||
~~~
|
|
||||||
.. _xref_target:
|
|
||||||
|
|
||||||
Normal non-indented text.
|
|
||||||
|
|
||||||
This is :ref:`reference <xref_target>`.
|
|
||||||
|
|
||||||
(If xref target is followed by section title, can be just
|
|
||||||
:ref:`xref_target`).
|
|
||||||
~~~
|
|
||||||
|
|
||||||
* Linking to external URL:
|
|
||||||
```
|
|
||||||
`link text <http://foo.com/...>`_
|
|
||||||
```
|
|
||||||
|
|
||||||
* Referencing builtin singleton objects:
|
|
||||||
```
|
|
||||||
``None``, ``True``, ``False``
|
|
||||||
```
|
|
||||||
|
|
||||||
* Use following syntax to create common description for more than one element:
|
|
||||||
~~~
|
|
||||||
.. function:: foo(x)
|
|
||||||
bar(y)
|
|
||||||
|
|
||||||
Description common to foo() and bar().
|
|
||||||
~~~
|
|
||||||
|
|
||||||
|
|
||||||
More detailed guides and quickrefs:
|
|
||||||
|
|
||||||
* http://www.sphinx-doc.org/en/stable/rest.html
|
|
||||||
* http://www.sphinx-doc.org/en/stable/markup/inline.html
|
|
||||||
* http://docutils.sourceforge.net/docs/user/rst/quickref.html
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
MicroPython Code of Conduct
|
|
||||||
===========================
|
|
||||||
|
|
||||||
The MicroPython community is made up of members from around the globe with a
|
|
||||||
diverse set of skills, personalities, and experiences. It is through these
|
|
||||||
differences that our community experiences great successes and continued growth.
|
|
||||||
When you're working with members of the community, this Code of Conduct will
|
|
||||||
help steer your interactions and keep MicroPython a positive, successful, and
|
|
||||||
growing community.
|
|
||||||
|
|
||||||
Members of the MicroPython community are open, considerate, and respectful.
|
|
||||||
Behaviours that reinforce these values contribute to a positive environment, and
|
|
||||||
include: acknowledging time and effort, being respectful of differing viewpoints
|
|
||||||
and experiences, gracefully accepting constructive criticism, and using
|
|
||||||
welcoming and inclusive language.
|
|
||||||
|
|
||||||
Every member of our community has the right to have their identity respected.
|
|
||||||
The MicroPython community is dedicated to providing a positive experience for
|
|
||||||
everyone, regardless of age, gender identity and expression, sexual orientation,
|
|
||||||
disability, physical appearance, body size, ethnicity, nationality, race, or
|
|
||||||
religion (or lack thereof), education, or socio-economic status.
|
|
||||||
|
|
||||||
Unacceptable behaviour includes: harassment, trolling, deliberate intimidation,
|
|
||||||
violent threats or language directed against another person; insults, put downs,
|
|
||||||
or jokes that are based upon stereotypes, that are exclusionary, or that hold
|
|
||||||
others up for ridicule; unwelcome sexual attention or advances; sustained
|
|
||||||
disruption of community discussions; publishing others' private information
|
|
||||||
without explicit permission; and other conduct that is inappropriate for a
|
|
||||||
professional audience including people of many different backgrounds.
|
|
||||||
|
|
||||||
This code of conduct covers all online and offline presence related to the
|
|
||||||
MicroPython project, including GitHub and the forum. If a participant engages
|
|
||||||
in behaviour that violates this code of conduct, the MicroPython team may take
|
|
||||||
action as they deem appropriate, including warning the offender or expulsion
|
|
||||||
from the community. Community members asked to stop any inappropriate behaviour
|
|
||||||
are expected to comply immediately.
|
|
||||||
|
|
||||||
Thank you for helping make this a welcoming, friendly community for everyone.
|
|
||||||
|
|
||||||
If you believe that someone is violating the code of conduct, or have any other
|
|
||||||
concerns, please contact a member of the MicroPython team by emailing
|
|
||||||
contact@micropython.org.
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
This Code of Conduct is licensed under the Creative Commons
|
|
||||||
Attribution-ShareAlike 3.0 Unported License.
|
|
||||||
|
|
||||||
Attributions
|
|
||||||
------------
|
|
||||||
|
|
||||||
Based on the Python code of conduct found at https://www.python.org/psf/conduct/
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013-2019 Damien P. George
|
Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -1,188 +0,0 @@
|
||||||
[![Build Status](https://travis-ci.org/micropython/micropython.png?branch=master)](https://travis-ci.org/micropython/micropython) [![Coverage Status](https://coveralls.io/repos/micropython/micropython/badge.png?branch=master)](https://coveralls.io/r/micropython/micropython?branch=master)
|
|
||||||
|
|
||||||
The MicroPython project
|
|
||||||
=======================
|
|
||||||
<p align="center">
|
|
||||||
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
This is the MicroPython project, which aims to put an implementation
|
|
||||||
of Python 3.x on microcontrollers and small embedded systems.
|
|
||||||
You can find the official website at [micropython.org](http://www.micropython.org).
|
|
||||||
|
|
||||||
WARNING: this project is in beta stage and is subject to changes of the
|
|
||||||
code-base, including project-wide name changes and API changes.
|
|
||||||
|
|
||||||
MicroPython implements the entire Python 3.4 syntax (including exceptions,
|
|
||||||
`with`, `yield from`, etc., and additionally `async`/`await` keywords from
|
|
||||||
Python 3.5). The following core datatypes are provided: `str` (including
|
|
||||||
basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`,
|
|
||||||
`frozenset`, `array.array`, `collections.namedtuple`, classes and instances.
|
|
||||||
Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have
|
|
||||||
support for `_thread` module (multithreading). Note that only a subset of
|
|
||||||
Python 3 functionality is implemented for the data types and modules.
|
|
||||||
|
|
||||||
MicroPython can execute scripts in textual source form or from precompiled
|
|
||||||
bytecode, in both cases either from an on-device filesystem or "frozen" into
|
|
||||||
the MicroPython executable.
|
|
||||||
|
|
||||||
See the repository http://github.com/micropython/pyboard for the MicroPython
|
|
||||||
board (PyBoard), the officially supported reference electronic circuit board.
|
|
||||||
|
|
||||||
Major components in this repository:
|
|
||||||
- py/ -- the core Python implementation, including compiler, runtime, and
|
|
||||||
core library.
|
|
||||||
- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts
|
|
||||||
into precompiled bytecode.
|
|
||||||
- ports/unix/ -- a version of MicroPython that runs on Unix.
|
|
||||||
- ports/stm32/ -- a version of MicroPython that runs on the PyBoard and similar
|
|
||||||
STM32 boards (using ST's Cube HAL drivers).
|
|
||||||
- ports/minimal/ -- a minimal MicroPython port. Start with this if you want
|
|
||||||
to port MicroPython to another microcontroller.
|
|
||||||
- tests/ -- test framework and test scripts.
|
|
||||||
- docs/ -- user documentation in Sphinx reStructuredText format. Rendered
|
|
||||||
HTML documentation is available at http://docs.micropython.org.
|
|
||||||
|
|
||||||
Additional components:
|
|
||||||
- ports/bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used
|
|
||||||
mostly to control code size.
|
|
||||||
- ports/teensy/ -- a version of MicroPython that runs on the Teensy 3.1
|
|
||||||
(preliminary but functional).
|
|
||||||
- ports/pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
|
|
||||||
- ports/cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
|
|
||||||
- ports/esp8266/ -- a version of MicroPython that runs on Espressif's ESP8266 SoC.
|
|
||||||
- ports/esp32/ -- a version of MicroPython that runs on Espressif's ESP32 SoC.
|
|
||||||
- ports/nrf/ -- a version of MicroPython that runs on Nordic's nRF51 and nRF52 MCUs.
|
|
||||||
- extmod/ -- additional (non-core) modules implemented in C.
|
|
||||||
- tools/ -- various tools, including the pyboard.py module.
|
|
||||||
- examples/ -- a few example Python scripts.
|
|
||||||
|
|
||||||
The subdirectories above may include READMEs with additional info.
|
|
||||||
|
|
||||||
"make" is used to build the components, or "gmake" on BSD-based systems.
|
|
||||||
You will also need bash, gcc, and Python 3.3+ available as the command `python3`
|
|
||||||
(if your system only has Python 2.7 then invoke make with the additional option
|
|
||||||
`PYTHON=python2`).
|
|
||||||
|
|
||||||
The MicroPython cross-compiler, mpy-cross
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
Most ports require the MicroPython cross-compiler to be built first. This
|
|
||||||
program, called mpy-cross, is used to pre-compile Python scripts to .mpy
|
|
||||||
files which can then be included (frozen) into the firmware/executable for
|
|
||||||
a port. To build mpy-cross use:
|
|
||||||
|
|
||||||
$ cd mpy-cross
|
|
||||||
$ make
|
|
||||||
|
|
||||||
The Unix version
|
|
||||||
----------------
|
|
||||||
|
|
||||||
The "unix" port requires a standard Unix environment with gcc and GNU make.
|
|
||||||
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
|
|
||||||
as ARM and MIPS. Making full-featured port to another architecture requires
|
|
||||||
writing some assembly code for the exception handling and garbage collection.
|
|
||||||
Alternatively, fallback implementation based on setjmp/longjmp can be used.
|
|
||||||
|
|
||||||
To build (see section below for required dependencies):
|
|
||||||
|
|
||||||
$ cd ports/unix
|
|
||||||
$ make submodules
|
|
||||||
$ make
|
|
||||||
|
|
||||||
Then to give it a try:
|
|
||||||
|
|
||||||
$ ./micropython
|
|
||||||
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
|
|
||||||
|
|
||||||
Use `CTRL-D` (i.e. EOF) to exit the shell.
|
|
||||||
Learn about command-line options (in particular, how to increase heap size
|
|
||||||
which may be needed for larger applications):
|
|
||||||
|
|
||||||
$ ./micropython --help
|
|
||||||
|
|
||||||
Run complete testsuite:
|
|
||||||
|
|
||||||
$ make test
|
|
||||||
|
|
||||||
Unix version comes with a builtin package manager called upip, e.g.:
|
|
||||||
|
|
||||||
$ ./micropython -m upip install micropython-pystone
|
|
||||||
$ ./micropython -m pystone
|
|
||||||
|
|
||||||
Browse available modules on
|
|
||||||
[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython).
|
|
||||||
Standard library modules come from
|
|
||||||
[micropython-lib](https://github.com/micropython/micropython-lib) project.
|
|
||||||
|
|
||||||
External dependencies
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Building MicroPython ports may require some dependencies installed.
|
|
||||||
|
|
||||||
For Unix port, `libffi` library and `pkg-config` tool are required. On
|
|
||||||
Debian/Ubuntu/Mint derivative Linux distros, install `build-essential`
|
|
||||||
(includes toolchain and make), `libffi-dev`, and `pkg-config` packages.
|
|
||||||
|
|
||||||
Other dependencies can be built together with MicroPython. This may
|
|
||||||
be required to enable extra features or capabilities, and in recent
|
|
||||||
versions of MicroPython, these may be enabled by default. To build
|
|
||||||
these additional dependencies, in the port directory you're
|
|
||||||
interested in (e.g. `ports/unix/`) first execute:
|
|
||||||
|
|
||||||
$ make submodules
|
|
||||||
|
|
||||||
This will fetch all the relevant git submodules (sub repositories) that
|
|
||||||
the port needs. Use the same command to get the latest versions of
|
|
||||||
submodules as they are updated from time to time. After that execute:
|
|
||||||
|
|
||||||
$ make deplibs
|
|
||||||
|
|
||||||
This will build all available dependencies (regardless whether they
|
|
||||||
are used or not). If you intend to build MicroPython with additional
|
|
||||||
options (like cross-compiling), the same set of options should be passed
|
|
||||||
to `make deplibs`. To actually enable/disable use of dependencies, edit
|
|
||||||
`ports/unix/mpconfigport.mk` file, which has inline descriptions of the options.
|
|
||||||
For example, to build SSL module (required for `upip` tool described above,
|
|
||||||
and so enabled by dfeault), `MICROPY_PY_USSL` should be set to 1.
|
|
||||||
|
|
||||||
For some ports, building required dependences is transparent, and happens
|
|
||||||
automatically. But they still need to be fetched with the `make submodules`
|
|
||||||
command.
|
|
||||||
|
|
||||||
The STM32 version
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
The "stm32" port requires an ARM compiler, arm-none-eabi-gcc, and associated
|
|
||||||
bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils,
|
|
||||||
arm-none-eabi-gcc and arm-none-eabi-newlib packages. Otherwise, try here:
|
|
||||||
https://launchpad.net/gcc-arm-embedded
|
|
||||||
|
|
||||||
To build:
|
|
||||||
|
|
||||||
$ cd ports/stm32
|
|
||||||
$ make submodules
|
|
||||||
$ make
|
|
||||||
|
|
||||||
You then need to get your board into DFU mode. On the pyboard, connect the
|
|
||||||
3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other
|
|
||||||
on the bottom left of the board, second row from the bottom).
|
|
||||||
|
|
||||||
Then to flash the code via USB DFU to your device:
|
|
||||||
|
|
||||||
$ make deploy
|
|
||||||
|
|
||||||
This will use the included `tools/pydfu.py` script. If flashing the firmware
|
|
||||||
does not work it may be because you don't have the correct permissions, and
|
|
||||||
need to use `sudo make deploy`.
|
|
||||||
See the README.md file in the ports/stm32/ directory for further details.
|
|
||||||
|
|
||||||
Contributing
|
|
||||||
------------
|
|
||||||
|
|
||||||
MicroPython is an open-source project and welcomes contributions. To be
|
|
||||||
productive, please be sure to follow the
|
|
||||||
[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines)
|
|
||||||
and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md).
|
|
||||||
Note that MicroPython is licenced under the MIT license, and all contributions
|
|
||||||
should follow this license.
|
|
154
README.md
154
README.md
|
@ -1,4 +1,152 @@
|
||||||
# Micropython for jebbatime
|
[![Build Status][travis-img]][travis-repo] [![Coverage Status][coveralls-img]][coveralls-repo]
|
||||||
This is a lesser fork of Daniel Thompson's fork of Micropython.
|
[travis-img]: https://travis-ci.org/micropython/micropython.png?branch=master
|
||||||
It is for the Pinetime watch.
|
[travis-repo]: https://travis-ci.org/micropython/micropython
|
||||||
|
[coveralls-img]: https://coveralls.io/repos/micropython/micropython/badge.png?branch=master
|
||||||
|
[coveralls-repo]: https://coveralls.io/r/micropython/micropython?branch=master
|
||||||
|
|
||||||
|
The MicroPython project
|
||||||
|
=======================
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://raw.githubusercontent.com/micropython/micropython/master/logo/upython-with-micro.jpg" alt="MicroPython Logo"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
This is the MicroPython project, which aims to put an implementation
|
||||||
|
of Python 3.x on microcontrollers and small embedded systems.
|
||||||
|
You can find the official website at [micropython.org](http://www.micropython.org).
|
||||||
|
|
||||||
|
WARNING: this project is in beta stage and is subject to changes of the
|
||||||
|
code-base, including project-wide name changes and API changes.
|
||||||
|
|
||||||
|
MicroPython implements the entire Python 3.4 syntax (including exceptions,
|
||||||
|
"with", "yield from", etc., and additionally "async" keyword from Python 3.5).
|
||||||
|
The following core datatypes are provided: str (including basic Unicode
|
||||||
|
support), bytes, bytearray, tuple, list, dict, set, frozenset, array.array,
|
||||||
|
collections.namedtuple, classes and instances. Builtin modules include sys,
|
||||||
|
time, and struct. Note that only subset of Python 3.4 functionality
|
||||||
|
implemented for the data types and modules.
|
||||||
|
|
||||||
|
See the repository www.github.com/micropython/pyboard for the Micro
|
||||||
|
Python board, the officially supported reference electronic circuit board.
|
||||||
|
|
||||||
|
Major components in this repository:
|
||||||
|
- py/ -- the core Python implementation, including compiler, runtime, and
|
||||||
|
core library.
|
||||||
|
- unix/ -- a version of MicroPython that runs on Unix.
|
||||||
|
- stmhal/ -- a version of MicroPython that runs on the MicroPython board
|
||||||
|
with an STM32F405RG (using ST's Cube HAL drivers).
|
||||||
|
- minimal/ -- a minimal MicroPython port. Start with this if you want
|
||||||
|
to port MicroPython to another microcontroller.
|
||||||
|
- tests/ -- test framework and test scripts.
|
||||||
|
- docs/ -- user documentation in Sphinx reStructuredText format.
|
||||||
|
|
||||||
|
Additional components:
|
||||||
|
- bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used
|
||||||
|
mostly to control code size.
|
||||||
|
- teensy/ -- a version of MicroPython that runs on the Teensy 3.1
|
||||||
|
(preliminary but functional).
|
||||||
|
- pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers.
|
||||||
|
- cc3200/ -- a version of MicroPython that runs on the CC3200 from TI.
|
||||||
|
- esp8266/ -- an experimental port for ESP8266 WiFi modules.
|
||||||
|
- tools/ -- various tools, including the pyboard.py module.
|
||||||
|
- examples/ -- a few example Python scripts.
|
||||||
|
|
||||||
|
The subdirectories above may include READMEs with additional info.
|
||||||
|
|
||||||
|
"make" is used to build the components, or "gmake" on BSD-based systems.
|
||||||
|
You will also need bash and Python (at least 2.7 or 3.3).
|
||||||
|
|
||||||
|
The Unix version
|
||||||
|
----------------
|
||||||
|
|
||||||
|
The "unix" port requires a standard Unix environment with gcc and GNU make.
|
||||||
|
x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well
|
||||||
|
as ARM and MIPS. Making full-featured port to another architecture requires
|
||||||
|
writing some assembly code for the exception handling and garbage collection.
|
||||||
|
Alternatively, fallback implementation based on setjmp/longjmp can be used.
|
||||||
|
|
||||||
|
To build (see section below for required dependencies):
|
||||||
|
|
||||||
|
$ cd unix
|
||||||
|
$ make axtls
|
||||||
|
$ make
|
||||||
|
|
||||||
|
Then to give it a try:
|
||||||
|
|
||||||
|
$ ./micropython
|
||||||
|
>>> list(5 * x + y for x in range(10) for y in [4, 2, 1])
|
||||||
|
|
||||||
|
Use `CTRL-D` (i.e. EOF) to exit the shell.
|
||||||
|
Learn about command-line options (in particular, how to increase heap size
|
||||||
|
which may be needed for larger applications):
|
||||||
|
|
||||||
|
$ ./micropython --help
|
||||||
|
|
||||||
|
Run complete testsuite:
|
||||||
|
|
||||||
|
$ make test
|
||||||
|
|
||||||
|
Unix version comes with a builtin package manager called upip, e.g.:
|
||||||
|
|
||||||
|
$ ./micropython -m upip install micropython-pystone
|
||||||
|
$ ./micropython -m pystone
|
||||||
|
|
||||||
|
Browse available modules on
|
||||||
|
[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython).
|
||||||
|
Standard library modules come from
|
||||||
|
[micropython-lib](https://github.com/micropython/micropython-lib) project.
|
||||||
|
|
||||||
|
External dependencies
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Building Unix version requires some dependencies installed. For
|
||||||
|
Debian/Ubuntu/Mint derivative Linux distros, install `build-essential`
|
||||||
|
(includes toolchain and make), `libffi-dev`, and `pkg-config` packages.
|
||||||
|
|
||||||
|
Other dependencies can be built together with MicroPython. Oftentimes,
|
||||||
|
you need to do this to enable extra features or capabilities. To build
|
||||||
|
these additional dependencies, first fetch git submodules for them:
|
||||||
|
|
||||||
|
$ git submodule update --init
|
||||||
|
|
||||||
|
Use this same command to get the latest versions of dependencies, as
|
||||||
|
they are updated from time to time. After that, in `unix/` dir, execute:
|
||||||
|
|
||||||
|
$ make deplibs
|
||||||
|
|
||||||
|
This will build all available dependencies (regardless whether they
|
||||||
|
are used or not). If you intend to build MicroPython with additional
|
||||||
|
options (like cross-compiling), the same set of options should be passed
|
||||||
|
to `make deplibs`. To actually enabled use of dependencies, edit
|
||||||
|
`unix/mpconfigport.mk` file, which has inline descriptions of the options.
|
||||||
|
For example, to build SSL module (required for `upip` tool described above),
|
||||||
|
set `MICROPY_PY_USSL` to 1.
|
||||||
|
|
||||||
|
In `unix/mpconfigport.mk`, you can also disable some dependencies enabled
|
||||||
|
by default, like FFI support, which requires libffi development files to
|
||||||
|
be installed.
|
||||||
|
|
||||||
|
The STM version
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The "stmhal" port requires an ARM compiler, arm-none-eabi-gcc, and associated
|
||||||
|
bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils and
|
||||||
|
arm-none-eabi-gcc packages. Otherwise, try here:
|
||||||
|
https://launchpad.net/gcc-arm-embedded
|
||||||
|
|
||||||
|
To build:
|
||||||
|
|
||||||
|
$ cd stmhal
|
||||||
|
$ make
|
||||||
|
|
||||||
|
You then need to get your board into DFU mode. On the pyboard, connect the
|
||||||
|
3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other
|
||||||
|
on the bottom left of the board, second row from the bottom).
|
||||||
|
|
||||||
|
Then to flash the code via USB DFU to your device:
|
||||||
|
|
||||||
|
$ make deploy
|
||||||
|
|
||||||
|
This will use the included `tools/pydfu.py` script. If flashing the firmware
|
||||||
|
does not work it may be because you don't have the correct permissions, and
|
||||||
|
need to use `sudo make deploy`.
|
||||||
|
See the README.md file in the stmhal/ directory for further details.
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
include ../py/mkenv.mk
|
||||||
|
|
||||||
|
# qstr definitions (must come before including py.mk)
|
||||||
|
QSTR_DEFS = qstrdefsport.h
|
||||||
|
|
||||||
|
# include py core make definitions
|
||||||
|
include ../py/py.mk
|
||||||
|
|
||||||
|
CROSS_COMPILE = arm-none-eabi-
|
||||||
|
|
||||||
|
INC += -I.
|
||||||
|
INC += -I..
|
||||||
|
INC += -I$(BUILD)
|
||||||
|
|
||||||
|
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||||
|
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) $(COPT)
|
||||||
|
|
||||||
|
#Debugging/Optimization
|
||||||
|
ifeq ($(DEBUG), 1)
|
||||||
|
CFLAGS += -O0 -ggdb
|
||||||
|
else
|
||||||
|
CFLAGS += -Os -DNDEBUG
|
||||||
|
endif
|
||||||
|
|
||||||
|
LDFLAGS = -nostdlib -T stm32f405.ld -Map=$@.map --cref
|
||||||
|
LIBS =
|
||||||
|
|
||||||
|
SRC_C = \
|
||||||
|
main.c \
|
||||||
|
# printf.c \
|
||||||
|
string0.c \
|
||||||
|
malloc0.c \
|
||||||
|
gccollect.c \
|
||||||
|
|
||||||
|
SRC_S = \
|
||||||
|
# startup_stm32f40xx.s \
|
||||||
|
gchelper.s \
|
||||||
|
|
||||||
|
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o))
|
||||||
|
|
||||||
|
all: $(BUILD)/firmware.elf
|
||||||
|
|
||||||
|
$(BUILD)/firmware.elf: $(OBJ)
|
||||||
|
$(ECHO) "LINK $@"
|
||||||
|
$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
$(Q)$(SIZE) $@
|
||||||
|
|
||||||
|
include ../py/mkrules.mk
|
|
@ -0,0 +1,99 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "py/nlr.h"
|
||||||
|
#include "py/compile.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/repl.h"
|
||||||
|
|
||||||
|
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
|
||||||
|
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
|
||||||
|
if (lex == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlr_buf_t nlr;
|
||||||
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
qstr source_name = lex->source_name;
|
||||||
|
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
|
||||||
|
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
|
||||||
|
mp_call_function_0(module_fun);
|
||||||
|
nlr_pop();
|
||||||
|
} else {
|
||||||
|
// uncaught exception
|
||||||
|
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
mp_init();
|
||||||
|
do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT);
|
||||||
|
do_str("for i in range(10):\n print(i)", MP_PARSE_FILE_INPUT);
|
||||||
|
mp_deinit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_import_stat_t mp_import_stat(const char *path) {
|
||||||
|
return MP_IMPORT_STAT_NO_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||||
|
return mp_const_none;
|
||||||
|
}
|
||||||
|
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||||
|
|
||||||
|
void nlr_jump_fail(void *val) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void NORETURN __fatal_error(const char *msg) {
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||||
|
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||||
|
__fatal_error("Assertion failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
int _lseek() {return 0;}
|
||||||
|
int _read() {return 0;}
|
||||||
|
int _write() {return 0;}
|
||||||
|
int _close() {return 0;}
|
||||||
|
void _exit(int x) {for(;;){}}
|
||||||
|
int _sbrk() {return 0;}
|
||||||
|
int _kill() {return 0;}
|
||||||
|
int _getpid() {return 0;}
|
||||||
|
int _fstat() {return 0;}
|
||||||
|
int _isatty() {return 0;}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *malloc(size_t n) {return NULL;}
|
||||||
|
void *calloc(size_t nmemb, size_t size) {return NULL;}
|
||||||
|
void *realloc(void *ptr, size_t size) {return NULL;}
|
||||||
|
void free(void *p) {}
|
||||||
|
int printf(const char *m, ...) {return 0;}
|
||||||
|
void *memcpy(void *dest, const void *src, size_t n) {return NULL;}
|
||||||
|
int memcmp(const void *s1, const void *s2, size_t n) {return 0;}
|
||||||
|
void *memmove(void *dest, const void *src, size_t n) {return NULL;}
|
||||||
|
void *memset(void *s, int c, size_t n) {return NULL;}
|
||||||
|
int strcmp(const char *s1, const char* s2) {return 0;}
|
||||||
|
int strncmp(const char *s1, const char* s2, size_t n) {return 0;}
|
||||||
|
size_t strlen(const char *s) {return 0;}
|
||||||
|
char *strcat(char *dest, const char *src) {return NULL;}
|
||||||
|
char *strchr(const char *dest, int c) {return NULL;}
|
||||||
|
#include <stdarg.h>
|
||||||
|
int vprintf(const char *format, va_list ap) {return 0;}
|
||||||
|
int vsnprintf(char *str, size_t size, const char *format, va_list ap) {return 0;}
|
||||||
|
|
||||||
|
#undef putchar
|
||||||
|
int putchar(int c) {return 0;}
|
||||||
|
int puts(const char *s) {return 0;}
|
||||||
|
|
||||||
|
void _start(void) {main(0, NULL);}
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// options to control how Micro Python is built
|
||||||
|
|
||||||
|
#define MICROPY_QSTR_BYTES_IN_HASH (1)
|
||||||
|
#define MICROPY_ALLOC_PATH_MAX (512)
|
||||||
|
#define MICROPY_EMIT_X64 (0)
|
||||||
|
#define MICROPY_EMIT_THUMB (0)
|
||||||
|
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||||
|
#define MICROPY_COMP_MODULE_CONST (0)
|
||||||
|
#define MICROPY_COMP_CONST (0)
|
||||||
|
#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0)
|
||||||
|
#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0)
|
||||||
|
#define MICROPY_MEM_STATS (0)
|
||||||
|
#define MICROPY_DEBUG_PRINTERS (0)
|
||||||
|
#define MICROPY_ENABLE_GC (0)
|
||||||
|
#define MICROPY_HELPER_REPL (0)
|
||||||
|
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||||
|
#define MICROPY_ENABLE_SOURCE_LINE (0)
|
||||||
|
#define MICROPY_ENABLE_DOC_STRING (0)
|
||||||
|
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||||
|
#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0)
|
||||||
|
#define MICROPY_PY_ASYNC_AWAIT (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_ENUMERATE (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_FROZENSET (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_REVERSED (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_SET (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_SLICE (0)
|
||||||
|
#define MICROPY_PY_BUILTINS_PROPERTY (0)
|
||||||
|
#define MICROPY_PY___FILE__ (0)
|
||||||
|
#define MICROPY_PY_GC (0)
|
||||||
|
#define MICROPY_PY_ARRAY (0)
|
||||||
|
#define MICROPY_PY_ATTRTUPLE (0)
|
||||||
|
#define MICROPY_PY_COLLECTIONS (0)
|
||||||
|
#define MICROPY_PY_MATH (0)
|
||||||
|
#define MICROPY_PY_CMATH (0)
|
||||||
|
#define MICROPY_PY_IO (0)
|
||||||
|
#define MICROPY_PY_STRUCT (0)
|
||||||
|
#define MICROPY_PY_SYS (0)
|
||||||
|
#define MICROPY_CPYTHON_COMPAT (0)
|
||||||
|
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
|
||||||
|
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
|
||||||
|
#define MICROPY_USE_INTERNAL_PRINTF (0)
|
||||||
|
|
||||||
|
// type definitions for the specific machine
|
||||||
|
|
||||||
|
#define BYTES_PER_WORD (4)
|
||||||
|
|
||||||
|
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1))
|
||||||
|
|
||||||
|
#define UINT_FMT "%lu"
|
||||||
|
#define INT_FMT "%ld"
|
||||||
|
|
||||||
|
typedef int32_t mp_int_t; // must be pointer size
|
||||||
|
typedef uint32_t mp_uint_t; // must be pointer size
|
||||||
|
typedef long mp_off_t;
|
||||||
|
|
||||||
|
// dummy print
|
||||||
|
#define MP_PLAT_PRINT_STRN(str, len) (void)0
|
||||||
|
|
||||||
|
// extra built in names to add to the global namespace
|
||||||
|
extern const struct _mp_obj_fun_builtin_t mp_builtin_open_obj;
|
||||||
|
#define MICROPY_PORT_BUILTINS \
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj },
|
||||||
|
|
||||||
|
// We need to provide a declaration/definition of alloca()
|
||||||
|
#include <alloca.h>
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
GNU linker script for STM32F405
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Specify the memory areas */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* entire flash, 1 MiB */
|
||||||
|
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 0x004000 /* sector 0, 16 KiB */
|
||||||
|
FLASH_TEXT (rx) : ORIGIN = 0x08020000, LENGTH = 0x080000 /* sectors 5,6,7,8, 4*128KiB = 512 KiB (could increase it more) */
|
||||||
|
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* top end of the stack */
|
||||||
|
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
|
||||||
|
/* RAM extents for the garbage collector */
|
||||||
|
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
_heap_end = 0x2001c000; /* tunable */
|
||||||
|
|
||||||
|
/* define output sections */
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* The startup code goes first into FLASH */
|
||||||
|
.isr_vector :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
KEEP(*(.isr_vector)) /* Startup code */
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH_ISR
|
||||||
|
|
||||||
|
/* The program code and other data goes into FLASH */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.text) /* .text sections (code) */
|
||||||
|
*(.text*) /* .text* sections (code) */
|
||||||
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
|
/* *(.glue_7) */ /* glue arm to thumb code */
|
||||||
|
/* *(.glue_7t) */ /* glue thumb to arm code */
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_etext = .; /* define a global symbol at end of code */
|
||||||
|
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
|
||||||
|
} >FLASH_TEXT
|
||||||
|
|
||||||
|
/*
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.ARM :
|
||||||
|
{
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
} >FLASH
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This is the initialized data section
|
||||||
|
The program executes knowing that the data is in the RAM
|
||||||
|
but the loader puts the initial values in the FLASH (inidata).
|
||||||
|
It is one task of the startup to copy the initial values from FLASH to RAM. */
|
||||||
|
.data : AT ( _sidata )
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
|
||||||
|
_ram_start = .; /* create a global symbol at ram start for garbage collector */
|
||||||
|
*(.data) /* .data sections */
|
||||||
|
*(.data*) /* .data* sections */
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* Uninitialized data section */
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_sbss = .; /* define a global symbol at bss start; used by startup code */
|
||||||
|
*(.bss)
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
_ebss = .; /* define a global symbol at bss end; used by startup code */
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* this is to define the start of the heap, and make sure we have a minimum size */
|
||||||
|
.heap :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
_heap_start = .; /* define a global symbol at heap start */
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* this just checks there is enough RAM for the stack */
|
||||||
|
.stack :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
/* Remove information from the standard libraries */
|
||||||
|
/*
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
libc.a ( * )
|
||||||
|
libm.a ( * )
|
||||||
|
libgcc.a ( * )
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
# Select the board to build for: if not given on the command line,
|
||||||
|
# then default to WIPY
|
||||||
|
BOARD ?= WIPY
|
||||||
|
ifeq ($(wildcard boards/$(BOARD)/.),)
|
||||||
|
$(error Invalid BOARD specified)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Make 'release' the default build type
|
||||||
|
BTYPE ?= release
|
||||||
|
|
||||||
|
# If the build directory is not given, make it reflect the board name.
|
||||||
|
BUILD ?= build/$(BOARD)/$(BTYPE)
|
||||||
|
|
||||||
|
include ../py/mkenv.mk
|
||||||
|
-include ../../localconfig.mk
|
||||||
|
|
||||||
|
CROSS_COMPILE ?= arm-none-eabi-
|
||||||
|
|
||||||
|
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -march=armv7e-m -mabi=aapcs -mcpu=cortex-m4 -msoft-float -mfloat-abi=soft -fsingle-precision-constant -Wdouble-promotion
|
||||||
|
CFLAGS = -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_CORTEX_M4) -Os
|
||||||
|
CFLAGS += -g -ffunction-sections -fdata-sections -fno-common -fsigned-char -mno-unaligned-access
|
||||||
|
CFLAGS += -Iboards/$(BOARD)
|
||||||
|
|
||||||
|
LDFLAGS = -Wl,-nostdlib -Wl,--gc-sections -Wl,-Map=$@.map
|
||||||
|
|
||||||
|
ifeq ($(BTARGET), application)
|
||||||
|
# qstr definitions (must come before including py.mk)
|
||||||
|
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
|
||||||
|
# include MicroPython make definitions
|
||||||
|
include ../py/py.mk
|
||||||
|
include application.mk
|
||||||
|
else
|
||||||
|
ifeq ($(BTARGET), bootloader)
|
||||||
|
include bootmgr/bootloader.mk
|
||||||
|
else
|
||||||
|
$(error Invalid BTARGET specified)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# always include MicroPython make rules
|
||||||
|
include ../py/mkrules.mk
|
|
@ -0,0 +1,93 @@
|
||||||
|
# Build Instructions for the CC3200
|
||||||
|
|
||||||
|
Currently the CC3200 port of MicroPython builds under Linux and OSX **but not under Windows**.
|
||||||
|
|
||||||
|
The tool chain required for the build can be found at <https://launchpad.net/gcc-arm-embedded>.
|
||||||
|
|
||||||
|
In order to download the image to the CC3200 you will need the CCS_Uniflash tool from TI, which at this
|
||||||
|
moment is only available for Windows, so, you need Linux/OSX to build and Windows to flash the image.
|
||||||
|
|
||||||
|
## To build an image suitable for debugging:
|
||||||
|
|
||||||
|
In order to debug the port specific code, optimizations need to be disabled on the
|
||||||
|
port file (check the Makefile for specific details). You can use CCS from TI.
|
||||||
|
Use the CC3200.ccxml file supplied with this distribution for the debuuger configuration.
|
||||||
|
```bash
|
||||||
|
make BTARGET=application BTYPE=debug BOARD=LAUNCHXL
|
||||||
|
```
|
||||||
|
## To build an image suitable to be flashed to the device:
|
||||||
|
```bash
|
||||||
|
make BTARGET=application BTYPE=release BOARD=LAUNCHXL
|
||||||
|
```
|
||||||
|
## Building the bootloader
|
||||||
|
```bash
|
||||||
|
make BTARGET=bootloader BTYPE=release BOARD=LAUNCHXL
|
||||||
|
```
|
||||||
|
|
||||||
|
## Regarding old revisions of the CC3200-LAUNCHXL
|
||||||
|
First silicon (pre-release) revisions of the CC3200 had issues with the ram blocks, and MicroPython cannot run
|
||||||
|
there. Make sure to use a **v4.1 (or higer) LAUNCHXL board** when trying this port, otherwise it won't work.
|
||||||
|
|
||||||
|
## Flashing the CC3200
|
||||||
|
- Make sure that you have built both the *bootloader* and the *application* in **release** mode.
|
||||||
|
- Make sure the SOP2 jumper is in position.
|
||||||
|
- Open CCS_Uniflash and connect to the board (by default on port 22).
|
||||||
|
- Format the serial flash (select 1MB size in case of the CC3200-LAUNCHXL, 2MB in case of the WiPy, leave the rest unchecked).
|
||||||
|
- Mark the following files for erasing: `/cert/ca.pem`, `/cert/client.pem`, `/cert/private.key` and `/tmp/pac.bin`.
|
||||||
|
- Add a new file with the name of /sys/mcuimg.bin, and select the URL to point to cc3200\bootmgr\build\<BOARD_NAME>\bootloader.bin.
|
||||||
|
- Add another file with the name of /sys/factimg.bin, and select the URL to point to cc3200\build\<BOARD_NAME>\mcuimg.bin.
|
||||||
|
- Click "Program" to apply all changes.
|
||||||
|
- Flash the latest service pack (servicepack_1.0.0.10.0.bin) using the "Service Pack Update" button.
|
||||||
|
- Close CCS_Uniflash, remove the SOP2 jumper and reset the board.
|
||||||
|
|
||||||
|
## Updating the board to with new software version
|
||||||
|
- Make sure the board is running and connected to the same network as the computer.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make BTARGET=application BTYPE=release BOARD=LAUNCHXL WIPY_IP=192.168.1.1 WIPY_USER=micro WIPY_PWD=python deploy
|
||||||
|
```
|
||||||
|
|
||||||
|
If `WIPY_IP`, `WIPY_USER` or `WIPY_PWD` are omitted the default values (the ones shown above) will be used.
|
||||||
|
|
||||||
|
## Playing with MicroPython and the CC3200:
|
||||||
|
|
||||||
|
Once the software is running, you have two options to access the MicroPython REPL:
|
||||||
|
|
||||||
|
- Through telnet.
|
||||||
|
* Connect to the network created by the board (as boots up in AP mode), **ssid = "wipy-wlan", key = "www.wipy.io"**.
|
||||||
|
* You can also reinitialize the WLAN in station mode and connect to another AP, or in AP mode but with a
|
||||||
|
different ssid and/or key.
|
||||||
|
* Use your favourite telnet client with the following settings: **host = 192.168.1.1, port = 23.**
|
||||||
|
* Log in with **user = "micro" and password = "python"**
|
||||||
|
|
||||||
|
The board has a small file system of 192K (WiPy) or 64K (Launchpad) located in the serial flash connected to the CC3200.
|
||||||
|
SD cards are also supported, you can connect any SD card and configure the pinout using the SD class API.
|
||||||
|
|
||||||
|
## Uploading scripts:
|
||||||
|
|
||||||
|
To upload your MicroPython scripts to the FTP server, open your FTP client of choice and connect to:
|
||||||
|
**ftp://192.168.1.1, user = "micro", password = "python"**
|
||||||
|
|
||||||
|
I have tested the FTP server with **FileZilla, FireFTP, FireFox, IE and Chrome,** other clients should work as well, but I am
|
||||||
|
not 100% sure of it.
|
||||||
|
|
||||||
|
## Upgrading the firmware Over The Air:
|
||||||
|
|
||||||
|
OTA software updates can be performed through the FTP server. After building a new **mcuimg.bin** in release mode, upload it to:
|
||||||
|
`/flash/sys/mcuimg.bin` it will take around 6s (The TI simplelink file system is quite slow because every file is mirrored for
|
||||||
|
safety). You won't see the file being stored inside `/flash/sys/` because it's actually saved bypassing FatFS, but rest assured that
|
||||||
|
the file was successfully transferred, and it has been signed with a MD5 checksum to verify its integrity.
|
||||||
|
Now, reset the MCU by pressing the switch on the board, or by typing:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import machine
|
||||||
|
machine.reset()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Note regarding FileZilla:
|
||||||
|
|
||||||
|
Do not use the quick connect button, instead, open the site manager and create a new configuration. In the "General" tab make
|
||||||
|
sure that encryption is set to: "Only use plain FTP (insecure)". In the Transfer Settings tab limit the max number of connections
|
||||||
|
to one, otherwise FileZilla will try to open a second command connection when retrieving and saving files, and for simplicity and
|
||||||
|
to reduce code size, only one command and one data connections are possible.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -37,7 +37,7 @@ ENTRY(ResetISR)
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
/* place the FreeRTOS heap (the MicroPython stack will live here) */
|
/* place the FreeRTOS heap (the micropython stack will live here) */
|
||||||
.rtos_heap (NOLOAD) :
|
.rtos_heap (NOLOAD) :
|
||||||
{
|
{
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
|
@ -83,7 +83,7 @@ SECTIONS
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
/* place here functions that are only called during boot up, */
|
/* place here functions that are only called during boot up, */
|
||||||
/* that way, we can re-use this area for the MicroPython heap */
|
/* that way, we can re-use this area for the micropython heap */
|
||||||
.boot :
|
.boot :
|
||||||
{
|
{
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
||||||
|
@ -93,7 +93,7 @@ SECTIONS
|
||||||
_eboot = .;
|
_eboot = .;
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
/* allocate the MicroPython heap */
|
/* allocate the micropython heap */
|
||||||
.heap :
|
.heap :
|
||||||
{
|
{
|
||||||
. = ALIGN(8);
|
. = ALIGN(8);
|
|
@ -1,5 +1,5 @@
|
||||||
APP_INC = -I.
|
APP_INC = -I.
|
||||||
APP_INC += -I$(TOP)
|
APP_INC += -I..
|
||||||
APP_INC += -Ifatfs/src
|
APP_INC += -Ifatfs/src
|
||||||
APP_INC += -Ifatfs/src/drivers
|
APP_INC += -Ifatfs/src/drivers
|
||||||
APP_INC += -IFreeRTOS
|
APP_INC += -IFreeRTOS
|
||||||
|
@ -10,7 +10,7 @@ APP_INC += -Ihal
|
||||||
APP_INC += -Ihal/inc
|
APP_INC += -Ihal/inc
|
||||||
APP_INC += -Imisc
|
APP_INC += -Imisc
|
||||||
APP_INC += -Imods
|
APP_INC += -Imods
|
||||||
APP_INC += -I$(TOP)/drivers/cc3100/inc
|
APP_INC += -I../drivers/cc3100/inc
|
||||||
APP_INC += -Isimplelink
|
APP_INC += -Isimplelink
|
||||||
APP_INC += -Isimplelink/oslib
|
APP_INC += -Isimplelink/oslib
|
||||||
APP_INC += -Itelnet
|
APP_INC += -Itelnet
|
||||||
|
@ -18,13 +18,20 @@ APP_INC += -Iutil
|
||||||
APP_INC += -Ibootmgr
|
APP_INC += -Ibootmgr
|
||||||
APP_INC += -I$(BUILD)
|
APP_INC += -I$(BUILD)
|
||||||
APP_INC += -I$(BUILD)/genhdr
|
APP_INC += -I$(BUILD)/genhdr
|
||||||
APP_INC += -I$(TOP)/ports/stm32
|
APP_INC += -I../lib/fatfs
|
||||||
|
APP_INC += -I../lib/mp-readline
|
||||||
|
APP_INC += -I../lib/netutils
|
||||||
|
APP_INC += -I../lib/timeutils
|
||||||
|
APP_INC += -I../stmhal
|
||||||
|
|
||||||
APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
APP_CPPDEFINES = -Dgcc -DTARGET_IS_CC3200 -DSL_FULL -DUSE_FREERTOS
|
||||||
|
|
||||||
APP_FATFS_SRC_C = $(addprefix fatfs/src/,\
|
APP_FATFS_SRC_C = $(addprefix fatfs/src/,\
|
||||||
drivers/sflash_diskio.c \
|
drivers/sflash_diskio.c \
|
||||||
drivers/sd_diskio.c \
|
drivers/sd_diskio.c \
|
||||||
|
option/syscall.c \
|
||||||
|
diskio.c \
|
||||||
|
ffconf.c \
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_RTOS_SRC_C = $(addprefix FreeRTOS/Source/,\
|
APP_RTOS_SRC_C = $(addprefix FreeRTOS/Source/,\
|
||||||
|
@ -74,6 +81,7 @@ APP_MISC_SRC_C = $(addprefix misc/,\
|
||||||
mpirq.c \
|
mpirq.c \
|
||||||
mperror.c \
|
mperror.c \
|
||||||
mpexception.c \
|
mpexception.c \
|
||||||
|
mpsystick.c \
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_MODS_SRC_C = $(addprefix mods/,\
|
APP_MODS_SRC_C = $(addprefix mods/,\
|
||||||
|
@ -90,7 +98,6 @@ APP_MODS_SRC_C = $(addprefix mods/,\
|
||||||
pybpin.c \
|
pybpin.c \
|
||||||
pybi2c.c \
|
pybi2c.c \
|
||||||
pybrtc.c \
|
pybrtc.c \
|
||||||
pybflash.c \
|
|
||||||
pybsd.c \
|
pybsd.c \
|
||||||
pybsleep.c \
|
pybsleep.c \
|
||||||
pybspi.c \
|
pybspi.c \
|
||||||
|
@ -128,6 +135,7 @@ APP_UTIL_SRC_C = $(addprefix util/,\
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_UTIL_SRC_S = $(addprefix util/,\
|
APP_UTIL_SRC_S = $(addprefix util/,\
|
||||||
|
gchelper.s \
|
||||||
sleeprestore.s \
|
sleeprestore.s \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -135,30 +143,33 @@ APP_MAIN_SRC_C = \
|
||||||
main.c \
|
main.c \
|
||||||
mptask.c \
|
mptask.c \
|
||||||
mpthreadport.c \
|
mpthreadport.c \
|
||||||
serverstask.c \
|
serverstask.c
|
||||||
fatfs_port.c \
|
|
||||||
|
|
||||||
APP_LIB_SRC_C = $(addprefix lib/,\
|
APP_LIB_SRC_C = $(addprefix lib/,\
|
||||||
oofatfs/ff.c \
|
fatfs/ff.c \
|
||||||
oofatfs/ffunicode.c \
|
fatfs/option/ccsbcs.c \
|
||||||
libc/string0.c \
|
libc/string0.c \
|
||||||
mp-readline/readline.c \
|
mp-readline/readline.c \
|
||||||
netutils/netutils.c \
|
netutils/netutils.c \
|
||||||
timeutils/timeutils.c \
|
timeutils/timeutils.c \
|
||||||
utils/pyexec.c \
|
utils/pyexec.c \
|
||||||
utils/interrupt_char.c \
|
utils/pyhelp.c \
|
||||||
utils/sys_stdio_mphal.c \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
APP_STM_SRC_C = $(addprefix ports/stm32/,\
|
APP_STM_SRC_C = $(addprefix stmhal/,\
|
||||||
bufhelper.c \
|
bufhelper.c \
|
||||||
|
builtin_open.c \
|
||||||
|
import.c \
|
||||||
|
input.c \
|
||||||
irq.c \
|
irq.c \
|
||||||
|
lexerfatfs.c \
|
||||||
|
moduselect.c \
|
||||||
|
pybstdio.c \
|
||||||
)
|
)
|
||||||
|
|
||||||
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(APP_FATFS_SRC_C:.c=.o) $(APP_RTOS_SRC_C:.c=.o) $(APP_FTP_SRC_C:.c=.o) $(APP_HAL_SRC_C:.c=.o) $(APP_MISC_SRC_C:.c=.o))
|
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(APP_FATFS_SRC_C:.c=.o) $(APP_RTOS_SRC_C:.c=.o) $(APP_FTP_SRC_C:.c=.o) $(APP_HAL_SRC_C:.c=.o) $(APP_MISC_SRC_C:.c=.o))
|
||||||
OBJ += $(addprefix $(BUILD)/, $(APP_MODS_SRC_C:.c=.o) $(APP_CC3100_SRC_C:.c=.o) $(APP_SL_SRC_C:.c=.o) $(APP_TELNET_SRC_C:.c=.o) $(APP_UTIL_SRC_C:.c=.o) $(APP_UTIL_SRC_S:.s=.o))
|
OBJ += $(addprefix $(BUILD)/, $(APP_MODS_SRC_C:.c=.o) $(APP_CC3100_SRC_C:.c=.o) $(APP_SL_SRC_C:.c=.o) $(APP_TELNET_SRC_C:.c=.o) $(APP_UTIL_SRC_C:.c=.o) $(APP_UTIL_SRC_S:.s=.o))
|
||||||
OBJ += $(addprefix $(BUILD)/, $(APP_MAIN_SRC_C:.c=.o) $(APP_LIB_SRC_C:.c=.o) $(APP_STM_SRC_C:.c=.o))
|
OBJ += $(addprefix $(BUILD)/, $(APP_MAIN_SRC_C:.c=.o) $(APP_LIB_SRC_C:.c=.o) $(APP_STM_SRC_C:.c=.o))
|
||||||
OBJ += $(BUILD)/lib/utils/gchelper_m3.o
|
|
||||||
OBJ += $(BUILD)/pins.o
|
OBJ += $(BUILD)/pins.o
|
||||||
|
|
||||||
# List of sources for qstr extraction
|
# List of sources for qstr extraction
|
||||||
|
@ -197,9 +208,9 @@ WIPY_PWD ?= 'python'
|
||||||
|
|
||||||
all: $(BUILD)/mcuimg.bin
|
all: $(BUILD)/mcuimg.bin
|
||||||
|
|
||||||
.PHONY: deploy-ota
|
.PHONY: deploy
|
||||||
|
|
||||||
deploy-ota: $(BUILD)/mcuimg.bin
|
deploy: $(BUILD)/mcuimg.bin
|
||||||
$(ECHO) "Writing $< to the board"
|
$(ECHO) "Writing $< to the board"
|
||||||
$(Q)$(PYTHON) $(UPDATE_WIPY) --verify --ip $(WIPY_IP) --user $(WIPY_USER) --password $(WIPY_PWD) --file $<
|
$(Q)$(PYTHON) $(UPDATE_WIPY) --verify --ip $(WIPY_IP) --user $(WIPY_USER) --password $(WIPY_PWD) --file $<
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
* Copyright (c) 2015 Daniel Campora
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LAUNCHXL
|
||||||
|
|
||||||
|
#define MICROPY_HW_BOARD_NAME "LaunchPad"
|
||||||
|
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||||
|
|
||||||
|
#define MICROPY_HW_ANTENNA_DIVERSITY (0)
|
||||||
|
|
||||||
|
#define MICROPY_STDIO_UART 0
|
||||||
|
#define MICROPY_STDIO_UART_BAUD 115200
|
||||||
|
|
||||||
|
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA1
|
||||||
|
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA2
|
||||||
|
#define MICROPY_SYS_LED_PORT GPIOA1_BASE
|
||||||
|
#define MICROPY_SAFE_BOOT_PORT GPIOA2_BASE
|
||||||
|
#define MICROPY_SYS_LED_GPIO pin_GP9
|
||||||
|
#define MICROPY_SYS_LED_PIN_NUM PIN_64 // GP9
|
||||||
|
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_15 // GP22
|
||||||
|
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
|
||||||
|
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_6
|
||||||
|
|
||||||
|
#define MICROPY_PORT_SFLASH_BLOCK_COUNT 32
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
* Copyright (c) 2015 Daniel Campora
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WIPY
|
||||||
|
|
||||||
|
#define MICROPY_HW_BOARD_NAME "WiPy"
|
||||||
|
#define MICROPY_HW_MCU_NAME "CC3200"
|
||||||
|
|
||||||
|
#define MICROPY_HW_ANTENNA_DIVERSITY (1)
|
||||||
|
|
||||||
|
#define MICROPY_SYS_LED_PRCM PRCM_GPIOA3
|
||||||
|
#define MICROPY_SAFE_BOOT_PRCM PRCM_GPIOA3
|
||||||
|
#define MICROPY_SYS_LED_PORT GPIOA3_BASE
|
||||||
|
#define MICROPY_SAFE_BOOT_PORT GPIOA3_BASE
|
||||||
|
#define MICROPY_SYS_LED_GPIO pin_GP25
|
||||||
|
#define MICROPY_SYS_LED_PIN_NUM PIN_21 // GP25 (SOP2)
|
||||||
|
#define MICROPY_SAFE_BOOT_PIN_NUM PIN_18 // GP28
|
||||||
|
#define MICROPY_SYS_LED_PORT_PIN GPIO_PIN_1
|
||||||
|
#define MICROPY_SAFE_BOOT_PORT_PIN GPIO_PIN_4
|
||||||
|
|
||||||
|
#define MICROPY_PORT_SFLASH_BLOCK_COUNT 96
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
|
@ -0,0 +1,233 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""Generates the pins file for the CC3200."""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import csv
|
||||||
|
|
||||||
|
|
||||||
|
SUPPORTED_AFS = { 'UART': ('TX', 'RX', 'RTS', 'CTS'),
|
||||||
|
'SPI': ('CLK', 'MOSI', 'MISO', 'CS0'),
|
||||||
|
#'I2S': ('CLK', 'FS', 'DAT0', 'DAT1'),
|
||||||
|
'I2C': ('SDA', 'SCL'),
|
||||||
|
'TIM': ('PWM'),
|
||||||
|
'SD': ('CLK', 'CMD', 'DAT0'),
|
||||||
|
'ADC': ('CH0', 'CH1', 'CH2', 'CH3')
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_port_pin(name_str):
|
||||||
|
"""Parses a string and returns a (port, gpio_bit) tuple."""
|
||||||
|
if len(name_str) < 3:
|
||||||
|
raise ValueError("Expecting pin name to be at least 3 characters")
|
||||||
|
if name_str[:2] != 'GP':
|
||||||
|
raise ValueError("Expecting pin name to start with GP")
|
||||||
|
if not name_str[2:].isdigit():
|
||||||
|
raise ValueError("Expecting numeric GPIO number")
|
||||||
|
port = int(int(name_str[2:]) / 8)
|
||||||
|
gpio_bit = 1 << int(int(name_str[2:]) % 8)
|
||||||
|
return (port, gpio_bit)
|
||||||
|
|
||||||
|
|
||||||
|
class AF:
|
||||||
|
"""Holds the description of an alternate function"""
|
||||||
|
def __init__(self, name, idx, fn, unit, type):
|
||||||
|
self.name = name
|
||||||
|
self.idx = idx
|
||||||
|
if self.idx > 15:
|
||||||
|
self.idx = -1
|
||||||
|
self.fn = fn
|
||||||
|
self.unit = unit
|
||||||
|
self.type = type
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
print (' AF({:16s}, {:4d}, {:8s}, {:4d}, {:8s}), // {}'.format(self.name, self.idx, self.fn, self.unit, self.type, self.name))
|
||||||
|
|
||||||
|
|
||||||
|
class Pin:
|
||||||
|
"""Holds the information associated with a pin."""
|
||||||
|
def __init__(self, name, port, gpio_bit, pin_num):
|
||||||
|
self.name = name
|
||||||
|
self.port = port
|
||||||
|
self.gpio_bit = gpio_bit
|
||||||
|
self.pin_num = pin_num
|
||||||
|
self.board_pin = False
|
||||||
|
self.afs = []
|
||||||
|
|
||||||
|
def add_af(self, af):
|
||||||
|
self.afs.append(af)
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
print('// {}'.format(self.name))
|
||||||
|
if len(self.afs):
|
||||||
|
print('const pin_af_t pin_{}_af[] = {{'.format(self.name))
|
||||||
|
for af in self.afs:
|
||||||
|
af.print()
|
||||||
|
print('};')
|
||||||
|
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, pin_{}_af, {});\n'.format(
|
||||||
|
self.name, self.name, self.port, self.gpio_bit, self.pin_num, self.name, len(self.afs)))
|
||||||
|
else:
|
||||||
|
print('pin_obj_t pin_{:4s} = PIN({:6s}, {:1d}, {:3d}, {:2d}, NULL, 0);\n'.format(
|
||||||
|
self.name, self.name, self.port, self.gpio_bit, self.pin_num))
|
||||||
|
|
||||||
|
def print_header(self, hdr_file):
|
||||||
|
hdr_file.write('extern pin_obj_t pin_{:s};\n'.format(self.name))
|
||||||
|
|
||||||
|
|
||||||
|
class Pins:
|
||||||
|
def __init__(self):
|
||||||
|
self.board_pins = [] # list of pin objects
|
||||||
|
|
||||||
|
def find_pin(self, port, gpio_bit):
|
||||||
|
for pin in self.board_pins:
|
||||||
|
if pin.port == port and pin.gpio_bit == gpio_bit:
|
||||||
|
return pin
|
||||||
|
|
||||||
|
def find_pin_by_num(self, pin_num):
|
||||||
|
for pin in self.board_pins:
|
||||||
|
if pin.pin_num == pin_num:
|
||||||
|
return pin
|
||||||
|
|
||||||
|
def find_pin_by_name(self, name):
|
||||||
|
for pin in self.board_pins:
|
||||||
|
if pin.name == name:
|
||||||
|
return pin
|
||||||
|
|
||||||
|
def parse_af_file(self, filename, pin_col, pinname_col, af_start_col):
|
||||||
|
with open(filename, 'r') as csvfile:
|
||||||
|
rows = csv.reader(csvfile)
|
||||||
|
for row in rows:
|
||||||
|
try:
|
||||||
|
(port_num, gpio_bit) = parse_port_pin(row[pinname_col])
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
if not row[pin_col].isdigit():
|
||||||
|
raise ValueError("Invalid pin number {:s} in row {:s}".format(row[pin_col]), row)
|
||||||
|
# Pin numbers must start from 0 when used with the TI API
|
||||||
|
pin_num = int(row[pin_col]) - 1;
|
||||||
|
pin = Pin(row[pinname_col], port_num, gpio_bit, pin_num)
|
||||||
|
self.board_pins.append(pin)
|
||||||
|
af_idx = 0
|
||||||
|
for af in row[af_start_col:]:
|
||||||
|
af_splitted = af.split('_')
|
||||||
|
fn_name = af_splitted[0].rstrip('0123456789')
|
||||||
|
if fn_name in SUPPORTED_AFS:
|
||||||
|
type_name = af_splitted[1]
|
||||||
|
if type_name in SUPPORTED_AFS[fn_name]:
|
||||||
|
unit_idx = af_splitted[0][-1]
|
||||||
|
pin.add_af(AF(af, af_idx, fn_name, int(unit_idx), type_name))
|
||||||
|
af_idx += 1
|
||||||
|
|
||||||
|
def parse_board_file(self, filename, cpu_pin_col):
|
||||||
|
with open(filename, 'r') as csvfile:
|
||||||
|
rows = csv.reader(csvfile)
|
||||||
|
for row in rows:
|
||||||
|
# Pin numbers must start from 0 when used with the TI API
|
||||||
|
if row[cpu_pin_col].isdigit():
|
||||||
|
pin = self.find_pin_by_num(int(row[cpu_pin_col]) - 1)
|
||||||
|
else:
|
||||||
|
pin = self.find_pin_by_name(row[cpu_pin_col])
|
||||||
|
if pin:
|
||||||
|
pin.board_pin = True
|
||||||
|
|
||||||
|
def print_named(self, label, pins):
|
||||||
|
print('')
|
||||||
|
print('STATIC const mp_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
|
||||||
|
for pin in pins:
|
||||||
|
if pin.board_pin:
|
||||||
|
print(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:6s}), (mp_obj_t)&pin_{:6s} }},'.format(pin.name, pin.name))
|
||||||
|
print('};')
|
||||||
|
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
for pin in self.board_pins:
|
||||||
|
if pin.board_pin:
|
||||||
|
pin.print()
|
||||||
|
self.print_named('board', self.board_pins)
|
||||||
|
print('')
|
||||||
|
|
||||||
|
def print_header(self, hdr_filename):
|
||||||
|
with open(hdr_filename, 'wt') as hdr_file:
|
||||||
|
for pin in self.board_pins:
|
||||||
|
if pin.board_pin:
|
||||||
|
pin.print_header(hdr_file)
|
||||||
|
|
||||||
|
def print_qstr(self, qstr_filename):
|
||||||
|
with open(qstr_filename, 'wt') as qstr_file:
|
||||||
|
pin_qstr_set = set([])
|
||||||
|
af_qstr_set = set([])
|
||||||
|
for pin in self.board_pins:
|
||||||
|
if pin.board_pin:
|
||||||
|
pin_qstr_set |= set([pin.name])
|
||||||
|
for af in pin.afs:
|
||||||
|
af_qstr_set |= set([af.name])
|
||||||
|
print('// Board pins', file=qstr_file)
|
||||||
|
for qstr in sorted(pin_qstr_set):
|
||||||
|
print('Q({})'.format(qstr), file=qstr_file)
|
||||||
|
print('\n// Pin AFs', file=qstr_file)
|
||||||
|
for qstr in sorted(af_qstr_set):
|
||||||
|
print('Q({})'.format(qstr), file=qstr_file)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog="make-pins.py",
|
||||||
|
usage="%(prog)s [options] [command]",
|
||||||
|
description="Generate board specific pin file"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-a", "--af",
|
||||||
|
dest="af_filename",
|
||||||
|
help="Specifies the alternate function file for the chip",
|
||||||
|
default="cc3200_af.csv"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-b", "--board",
|
||||||
|
dest="board_filename",
|
||||||
|
help="Specifies the board file",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-p", "--prefix",
|
||||||
|
dest="prefix_filename",
|
||||||
|
help="Specifies beginning portion of generated pins file",
|
||||||
|
default="cc3200_prefix.c"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-q", "--qstr",
|
||||||
|
dest="qstr_filename",
|
||||||
|
help="Specifies name of generated qstr header file",
|
||||||
|
default="build/pins_qstr.h"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-r", "--hdr",
|
||||||
|
dest="hdr_filename",
|
||||||
|
help="Specifies name of generated pin header file",
|
||||||
|
default="build/pins.h"
|
||||||
|
)
|
||||||
|
args = parser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
pins = Pins()
|
||||||
|
|
||||||
|
print('// This file was automatically generated by make-pins.py')
|
||||||
|
print('//')
|
||||||
|
if args.af_filename:
|
||||||
|
print('// --af {:s}'.format(args.af_filename))
|
||||||
|
pins.parse_af_file(args.af_filename, 0, 1, 3)
|
||||||
|
|
||||||
|
if args.board_filename:
|
||||||
|
print('// --board {:s}'.format(args.board_filename))
|
||||||
|
pins.parse_board_file(args.board_filename, 1)
|
||||||
|
|
||||||
|
if args.prefix_filename:
|
||||||
|
print('// --prefix {:s}'.format(args.prefix_filename))
|
||||||
|
print('')
|
||||||
|
with open(args.prefix_filename, 'r') as prefix_file:
|
||||||
|
print(prefix_file.read())
|
||||||
|
pins.print()
|
||||||
|
pins.print_qstr(args.qstr_filename)
|
||||||
|
pins.print_header(args.hdr_filename)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -4,13 +4,13 @@ BOOT_INC = -Ibootmgr
|
||||||
BOOT_INC += -Ibootmgr/sl
|
BOOT_INC += -Ibootmgr/sl
|
||||||
BOOT_INC += -Ihal
|
BOOT_INC += -Ihal
|
||||||
BOOT_INC += -Ihal/inc
|
BOOT_INC += -Ihal/inc
|
||||||
BOOT_INC += -I$(TOP)/drivers/cc3100/inc
|
BOOT_INC += -I../drivers/cc3100/inc
|
||||||
BOOT_INC += -Imisc
|
BOOT_INC += -Imisc
|
||||||
BOOT_INC += -Imods
|
BOOT_INC += -Imods
|
||||||
BOOT_INC += -Isimplelink
|
BOOT_INC += -Isimplelink
|
||||||
BOOT_INC += -Isimplelink/oslib
|
BOOT_INC += -Isimplelink/oslib
|
||||||
BOOT_INC += -Iutil
|
BOOT_INC += -Iutil
|
||||||
BOOT_INC += -I$(TOP)
|
BOOT_INC += -I..
|
||||||
BOOT_INC += -I.
|
BOOT_INC += -I.
|
||||||
BOOT_INC += -I$(BUILD)
|
BOOT_INC += -I$(BUILD)
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ $(BUILD)/misc/%.o: CFLAGS += -Os
|
||||||
$(BUILD)/simplelink/%.o: CFLAGS += -Os
|
$(BUILD)/simplelink/%.o: CFLAGS += -Os
|
||||||
$(BUILD)/drivers/cc3100/%.o: CFLAGS += -Os
|
$(BUILD)/drivers/cc3100/%.o: CFLAGS += -Os
|
||||||
$(BUILD)/py/%.o: CFLAGS += -Os
|
$(BUILD)/py/%.o: CFLAGS += -Os
|
||||||
$(BUILD)/ports/stm32/%.o: CFLAGS += -Os
|
$(BUILD)/stmhal/%.o: CFLAGS += -Os
|
||||||
else
|
else
|
||||||
$(error Invalid BTYPE specified)
|
$(error Invalid BTYPE specified)
|
||||||
endif
|
endif
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -23,8 +23,9 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_CC3200_BOOTMGR_BOOTMGR_H
|
|
||||||
#define MICROPY_INCLUDED_CC3200_BOOTMGR_BOOTMGR_H
|
#ifndef __BOOTMGR_H__
|
||||||
|
#define __BOOTMGR_H__
|
||||||
|
|
||||||
//****************************************************************************
|
//****************************************************************************
|
||||||
//
|
//
|
||||||
|
@ -65,4 +66,4 @@ extern void Run(unsigned long);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_CC3200_BOOTMGR_BOOTMGR_H
|
#endif //__BOOTMGR_H__
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -23,8 +23,9 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_CC3200_BOOTMGR_FLC_H
|
|
||||||
#define MICROPY_INCLUDED_CC3200_BOOTMGR_FLC_H
|
#ifndef __FLC_H__
|
||||||
|
#define __FLC_H__
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
||||||
|
@ -92,4 +93,4 @@ typedef struct _sBootInfo_t
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_CC3200_BOOTMGR_FLC_H
|
#endif /* __FLC_H__ */
|
|
@ -0,0 +1,420 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Daniel Campora
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "std.h"
|
||||||
|
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
#include "hw_ints.h"
|
||||||
|
#include "hw_types.h"
|
||||||
|
#include "hw_gpio.h"
|
||||||
|
#include "hw_memmap.h"
|
||||||
|
#include "hw_gprcm.h"
|
||||||
|
#include "hw_common_reg.h"
|
||||||
|
#include "pin.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "rom_map.h"
|
||||||
|
#include "prcm.h"
|
||||||
|
#include "simplelink.h"
|
||||||
|
#include "interrupt.h"
|
||||||
|
#include "gpio.h"
|
||||||
|
#include "flc.h"
|
||||||
|
#include "bootmgr.h"
|
||||||
|
#include "shamd5.h"
|
||||||
|
#include "cryptohash.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "cc3200_hal.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "mperror.h"
|
||||||
|
#include "antenna.h"
|
||||||
|
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Local Constants
|
||||||
|
//*****************************************************************************
|
||||||
|
#define SL_STOP_TIMEOUT 35
|
||||||
|
#define BOOTMGR_HASH_ALGO SHAMD5_ALGO_MD5
|
||||||
|
#define BOOTMGR_HASH_SIZE 32
|
||||||
|
#define BOOTMGR_BUFF_SIZE 512
|
||||||
|
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_0_MS 500
|
||||||
|
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_1_MS 3000
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS 500
|
||||||
|
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_2_MS 3000
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_2_BLINK_MS 250
|
||||||
|
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_3_MS 1500
|
||||||
|
#define BOOTMGR_WAIT_SAFE_MODE_3_BLINK_MS 100
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Exported functions declarations
|
||||||
|
//*****************************************************************************
|
||||||
|
extern void bootmgr_run_app (_u32 base);
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Local functions declarations
|
||||||
|
//*****************************************************************************
|
||||||
|
static void bootmgr_board_init (void);
|
||||||
|
static bool bootmgr_verify (_u8 *image);
|
||||||
|
static void bootmgr_load_and_execute (_u8 *image);
|
||||||
|
static bool wait_while_blinking (uint32_t wait_time, uint32_t period, bool force_wait);
|
||||||
|
static bool safe_boot_request_start (uint32_t wait_time);
|
||||||
|
static void wait_for_safe_boot (sBootInfo_t *psBootInfo);
|
||||||
|
static void bootmgr_image_loader (sBootInfo_t *psBootInfo);
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Private data
|
||||||
|
//*****************************************************************************
|
||||||
|
static _u8 bootmgr_file_buf[BOOTMGR_BUFF_SIZE];
|
||||||
|
static _u8 bootmgr_hash_buf[BOOTMGR_HASH_SIZE + 1];
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Vector Table
|
||||||
|
//*****************************************************************************
|
||||||
|
extern void (* const g_pfnVectors[])(void);
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// WLAN Event handler callback hookup function
|
||||||
|
//*****************************************************************************
|
||||||
|
void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// HTTP Server callback hookup function
|
||||||
|
//*****************************************************************************
|
||||||
|
void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent,
|
||||||
|
SlHttpServerResponse_t *pHttpResponse)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Net APP Event callback hookup function
|
||||||
|
//*****************************************************************************
|
||||||
|
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// General Event callback hookup function
|
||||||
|
//*****************************************************************************
|
||||||
|
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Socket Event callback hookup function
|
||||||
|
//*****************************************************************************
|
||||||
|
void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Board Initialization & Configuration
|
||||||
|
//*****************************************************************************
|
||||||
|
static void bootmgr_board_init(void) {
|
||||||
|
// set the vector table base
|
||||||
|
MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);
|
||||||
|
|
||||||
|
// enable processor interrupts
|
||||||
|
MAP_IntMasterEnable();
|
||||||
|
MAP_IntEnable(FAULT_SYSTICK);
|
||||||
|
|
||||||
|
// mandatory MCU initialization
|
||||||
|
PRCMCC3200MCUInit();
|
||||||
|
|
||||||
|
// clear all the special bits, since we can't trust their content after reset
|
||||||
|
// except for the WDT reset one!!
|
||||||
|
PRCMClearSpecialBit(PRCM_SAFE_BOOT_BIT);
|
||||||
|
PRCMClearSpecialBit(PRCM_FIRST_BOOT_BIT);
|
||||||
|
|
||||||
|
// check the reset after clearing the special bits
|
||||||
|
mperror_bootloader_check_reset_cause();
|
||||||
|
|
||||||
|
#if MICROPY_HW_ANTENNA_DIVERSITY
|
||||||
|
// configure the antenna selection pins
|
||||||
|
antenna_init0();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// enable the data hashing engine
|
||||||
|
CRYPTOHASH_Init();
|
||||||
|
|
||||||
|
// init the system led and the system switch
|
||||||
|
mperror_init0();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Verifies the integrity of the new application binary
|
||||||
|
//*****************************************************************************
|
||||||
|
static bool bootmgr_verify (_u8 *image) {
|
||||||
|
SlFsFileInfo_t FsFileInfo;
|
||||||
|
_u32 reqlen, offset = 0;
|
||||||
|
_i32 fHandle;
|
||||||
|
|
||||||
|
// open the file for reading
|
||||||
|
if (0 == sl_FsOpen(image, FS_MODE_OPEN_READ, NULL, &fHandle)) {
|
||||||
|
// get the file size
|
||||||
|
sl_FsGetInfo(image, 0, &FsFileInfo);
|
||||||
|
|
||||||
|
if (FsFileInfo.FileLen > BOOTMGR_HASH_SIZE) {
|
||||||
|
FsFileInfo.FileLen -= BOOTMGR_HASH_SIZE;
|
||||||
|
CRYPTOHASH_SHAMD5Start(BOOTMGR_HASH_ALGO, FsFileInfo.FileLen);
|
||||||
|
do {
|
||||||
|
if ((FsFileInfo.FileLen - offset) > BOOTMGR_BUFF_SIZE) {
|
||||||
|
reqlen = BOOTMGR_BUFF_SIZE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reqlen = FsFileInfo.FileLen - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += sl_FsRead(fHandle, offset, bootmgr_file_buf, reqlen);
|
||||||
|
CRYPTOHASH_SHAMD5Update(bootmgr_file_buf, reqlen);
|
||||||
|
} while (offset < FsFileInfo.FileLen);
|
||||||
|
|
||||||
|
CRYPTOHASH_SHAMD5Read (bootmgr_file_buf);
|
||||||
|
|
||||||
|
// convert the resulting hash to hex
|
||||||
|
for (_u32 i = 0; i < (BOOTMGR_HASH_SIZE / 2); i++) {
|
||||||
|
snprintf ((char *)&bootmgr_hash_buf[(i * 2)], 3, "%02x", bootmgr_file_buf[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the hash from the file and close it
|
||||||
|
sl_FsRead(fHandle, offset, bootmgr_file_buf, BOOTMGR_HASH_SIZE);
|
||||||
|
sl_FsClose (fHandle, NULL, NULL, 0);
|
||||||
|
bootmgr_file_buf[BOOTMGR_HASH_SIZE] = '\0';
|
||||||
|
// compare both hashes
|
||||||
|
if (!strcmp((const char *)bootmgr_hash_buf, (const char *)bootmgr_file_buf)) {
|
||||||
|
// it's a match
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// close the file
|
||||||
|
sl_FsClose(fHandle, NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Loads the application from sFlash and executes
|
||||||
|
//*****************************************************************************
|
||||||
|
static void bootmgr_load_and_execute (_u8 *image) {
|
||||||
|
SlFsFileInfo_t pFsFileInfo;
|
||||||
|
_i32 fhandle;
|
||||||
|
// open the application binary
|
||||||
|
if (!sl_FsOpen(image, FS_MODE_OPEN_READ, NULL, &fhandle)) {
|
||||||
|
// get the file size
|
||||||
|
if (!sl_FsGetInfo(image, 0, &pFsFileInfo)) {
|
||||||
|
// read the application into SRAM
|
||||||
|
if (pFsFileInfo.FileLen == sl_FsRead(fhandle, 0, (unsigned char *)APP_IMG_SRAM_OFFSET, pFsFileInfo.FileLen)) {
|
||||||
|
// close the file
|
||||||
|
sl_FsClose(fhandle, 0, 0, 0);
|
||||||
|
// stop the network services
|
||||||
|
sl_Stop(SL_STOP_TIMEOUT);
|
||||||
|
// execute the application
|
||||||
|
bootmgr_run_app(APP_IMG_SRAM_OFFSET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Wait while the safe mode pin is being held high and blink the system led
|
||||||
|
//! with the specified period
|
||||||
|
//*****************************************************************************
|
||||||
|
static bool wait_while_blinking (uint32_t wait_time, uint32_t period, bool force_wait) {
|
||||||
|
_u32 count;
|
||||||
|
for (count = 0; (force_wait || MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN)) &&
|
||||||
|
((period * count) < wait_time); count++) {
|
||||||
|
// toogle the led
|
||||||
|
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, ~MAP_GPIOPinRead(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN));
|
||||||
|
UtilsDelay(UTILS_DELAY_US_TO_COUNT(period * 1000));
|
||||||
|
}
|
||||||
|
return MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool safe_boot_request_start (uint32_t wait_time) {
|
||||||
|
if (MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN)) {
|
||||||
|
UtilsDelay(UTILS_DELAY_US_TO_COUNT(wait_time * 1000));
|
||||||
|
}
|
||||||
|
return MAP_GPIOPinRead(MICROPY_SAFE_BOOT_PORT, MICROPY_SAFE_BOOT_PORT_PIN) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Check for the safe mode pin
|
||||||
|
//*****************************************************************************
|
||||||
|
static void wait_for_safe_boot (sBootInfo_t *psBootInfo) {
|
||||||
|
if (safe_boot_request_start(BOOTMGR_WAIT_SAFE_MODE_0_MS)) {
|
||||||
|
if (wait_while_blinking(BOOTMGR_WAIT_SAFE_MODE_1_MS, BOOTMGR_WAIT_SAFE_MODE_1_BLINK_MS, false)) {
|
||||||
|
// go back one step in time
|
||||||
|
psBootInfo->ActiveImg = psBootInfo->PrevImg;
|
||||||
|
if (wait_while_blinking(BOOTMGR_WAIT_SAFE_MODE_2_MS, BOOTMGR_WAIT_SAFE_MODE_2_BLINK_MS, false)) {
|
||||||
|
// go back directly to the factory image
|
||||||
|
psBootInfo->ActiveImg = IMG_ACT_FACTORY;
|
||||||
|
wait_while_blinking(BOOTMGR_WAIT_SAFE_MODE_3_MS, BOOTMGR_WAIT_SAFE_MODE_3_BLINK_MS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// turn off the system led
|
||||||
|
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, 0);
|
||||||
|
// request a safe boot to the application
|
||||||
|
PRCMSetSpecialBit(PRCM_SAFE_BOOT_BIT);
|
||||||
|
}
|
||||||
|
// deinit the safe boot pin
|
||||||
|
mperror_deinit_sfe_pin();
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Load the proper image based on the information from the boot info
|
||||||
|
//! and launch it.
|
||||||
|
//*****************************************************************************
|
||||||
|
static void bootmgr_image_loader(sBootInfo_t *psBootInfo) {
|
||||||
|
_i32 fhandle;
|
||||||
|
_u8 *image;
|
||||||
|
|
||||||
|
// search for the active image
|
||||||
|
switch (psBootInfo->ActiveImg) {
|
||||||
|
case IMG_ACT_UPDATE1:
|
||||||
|
image = (unsigned char *)IMG_UPDATE1;
|
||||||
|
break;
|
||||||
|
case IMG_ACT_UPDATE2:
|
||||||
|
image = (unsigned char *)IMG_UPDATE2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
image = (unsigned char *)IMG_FACTORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have a new image that needs to be verified?
|
||||||
|
if ((psBootInfo->ActiveImg != IMG_ACT_FACTORY) && (psBootInfo->Status == IMG_STATUS_CHECK)) {
|
||||||
|
if (!bootmgr_verify(image)) {
|
||||||
|
// verification failed, delete the broken file
|
||||||
|
sl_FsDel(image, 0);
|
||||||
|
// switch to the previous image
|
||||||
|
psBootInfo->ActiveImg = psBootInfo->PrevImg;
|
||||||
|
psBootInfo->PrevImg = IMG_ACT_FACTORY;
|
||||||
|
}
|
||||||
|
// in any case, change the status to "READY"
|
||||||
|
psBootInfo->Status = IMG_STATUS_READY;
|
||||||
|
// write the new boot info
|
||||||
|
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_WRITE, NULL, &fhandle)) {
|
||||||
|
sl_FsWrite(fhandle, 0, (unsigned char *)psBootInfo, sizeof(sBootInfo_t));
|
||||||
|
// close the file
|
||||||
|
sl_FsClose(fhandle, 0, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this one might modify the boot info hence it MUST be called after
|
||||||
|
// bootmgr_verify! (so that the changes are not saved to flash)
|
||||||
|
wait_for_safe_boot(psBootInfo);
|
||||||
|
|
||||||
|
// select the active image again, since it might have changed
|
||||||
|
switch (psBootInfo->ActiveImg) {
|
||||||
|
case IMG_ACT_UPDATE1:
|
||||||
|
image = (unsigned char *)IMG_UPDATE1;
|
||||||
|
break;
|
||||||
|
case IMG_ACT_UPDATE2:
|
||||||
|
image = (unsigned char *)IMG_UPDATE2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
image = (unsigned char *)IMG_FACTORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bootmgr_load_and_execute(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! Main function
|
||||||
|
//*****************************************************************************
|
||||||
|
int main (void) {
|
||||||
|
sBootInfo_t sBootInfo = { .ActiveImg = IMG_ACT_FACTORY, .Status = IMG_STATUS_READY, .PrevImg = IMG_ACT_FACTORY };
|
||||||
|
bool bootapp = false;
|
||||||
|
_i32 fhandle;
|
||||||
|
|
||||||
|
// board setup
|
||||||
|
bootmgr_board_init();
|
||||||
|
|
||||||
|
// start simplelink since we need it to access the sflash
|
||||||
|
sl_Start(0, 0, 0);
|
||||||
|
|
||||||
|
// if a boot info file is found, load it, else, create a new one with the default boot info
|
||||||
|
if (!sl_FsOpen((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_READ, NULL, &fhandle)) {
|
||||||
|
if (sizeof(sBootInfo_t) == sl_FsRead(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t))) {
|
||||||
|
bootapp = true;
|
||||||
|
}
|
||||||
|
sl_FsClose(fhandle, 0, 0, 0);
|
||||||
|
}
|
||||||
|
// boot info file not present, it means that this is the first boot after being programmed
|
||||||
|
if (!bootapp) {
|
||||||
|
// create a new boot info file
|
||||||
|
_u32 BootInfoCreateFlag = _FS_FILE_OPEN_FLAG_COMMIT | _FS_FILE_PUBLIC_WRITE | _FS_FILE_PUBLIC_READ;
|
||||||
|
if (!sl_FsOpen ((unsigned char *)IMG_BOOT_INFO, FS_MODE_OPEN_CREATE((2 * sizeof(sBootInfo_t)),
|
||||||
|
BootInfoCreateFlag), NULL, &fhandle)) {
|
||||||
|
// write the default boot info.
|
||||||
|
if (sizeof(sBootInfo_t) == sl_FsWrite(fhandle, 0, (unsigned char *)&sBootInfo, sizeof(sBootInfo_t))) {
|
||||||
|
bootapp = true;
|
||||||
|
}
|
||||||
|
sl_FsClose(fhandle, 0, 0, 0);
|
||||||
|
}
|
||||||
|
// signal the first boot to the application
|
||||||
|
PRCMSetSpecialBit(PRCM_FIRST_BOOT_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bootapp) {
|
||||||
|
// load and execute the image based on the boot info
|
||||||
|
bootmgr_image_loader(&sBootInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop simplelink
|
||||||
|
sl_Stop(SL_STOP_TIMEOUT);
|
||||||
|
|
||||||
|
// if we've reached this point, then it means that a fatal error has occurred and the
|
||||||
|
// application could not be loaded, so, loop forever and signal the crash to the user
|
||||||
|
while (true) {
|
||||||
|
// keep the bld on
|
||||||
|
MAP_GPIOPinWrite(MICROPY_SYS_LED_PORT, MICROPY_SYS_LED_PORT_PIN, MICROPY_SYS_LED_PORT_PIN);
|
||||||
|
__asm volatile(" dsb \n"
|
||||||
|
" isb \n"
|
||||||
|
" wfi \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
//! The following stub function is needed to link mp_vprintf
|
||||||
|
//*****************************************************************************
|
||||||
|
#include "py/qstr.h"
|
||||||
|
|
||||||
|
const byte *qstr_data(qstr q, size_t *len) {
|
||||||
|
*len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2014 */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* If a working storage control module is available, it should be */
|
||||||
|
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||||
|
/* This is an example of glue functions to attach various exsisting */
|
||||||
|
/* storage control modules to the FatFs module with a defined API. */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
#include "py/obj.h"
|
||||||
|
#include "lib/fatfs/ff.h"
|
||||||
|
#include "lib/fatfs/diskio.h" /* FatFs lower layer API */
|
||||||
|
#include "sflash_diskio.h" /* Serial flash disk IO API */
|
||||||
|
#include "sd_diskio.h" /* SDCARD disk IO API */
|
||||||
|
#include "inc/hw_types.h"
|
||||||
|
#include "inc/hw_ints.h"
|
||||||
|
#include "inc/hw_memmap.h"
|
||||||
|
#include "rom_map.h"
|
||||||
|
#include "prcm.h"
|
||||||
|
#include "pybrtc.h"
|
||||||
|
#include "timeutils.h"
|
||||||
|
#include "pybsd.h"
|
||||||
|
#include "moduos.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Get Drive Status */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DSTATUS disk_status (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == PD_FLASH) {
|
||||||
|
return sflash_disk_status();
|
||||||
|
} else {
|
||||||
|
os_fs_mount_t *mount_obj;
|
||||||
|
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||||
|
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||||
|
return STA_PROTECT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STA_NODISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Inidialize a Drive */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DSTATUS disk_initialize (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == PD_FLASH) {
|
||||||
|
if (RES_OK != sflash_disk_init()) {
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os_fs_mount_t *mount_obj;
|
||||||
|
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||||
|
if (mount_obj->writeblocks[0] == MP_OBJ_NULL) {
|
||||||
|
return STA_PROTECT;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STA_NODISK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Read Sector(s) */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DRESULT disk_read (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
BYTE *buff, /* Data buffer to store read data */
|
||||||
|
DWORD sector, /* Sector address in LBA */
|
||||||
|
UINT count /* Number of sectors to read */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == PD_FLASH) {
|
||||||
|
return sflash_disk_read(buff, sector, count);
|
||||||
|
} else {
|
||||||
|
os_fs_mount_t *mount_obj;
|
||||||
|
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||||
|
// optimization for the built-in sd card device
|
||||||
|
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||||
|
return sd_disk_read(buff, sector, count);
|
||||||
|
}
|
||||||
|
mount_obj->readblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||||
|
mount_obj->readblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, buff);
|
||||||
|
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->readblocks));
|
||||||
|
}
|
||||||
|
// nothing mounted
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Write Sector(s) */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if _USE_WRITE
|
||||||
|
DRESULT disk_write (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
const BYTE *buff, /* Data to be written */
|
||||||
|
DWORD sector, /* Sector address in LBA */
|
||||||
|
UINT count /* Number of sectors to write */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == PD_FLASH) {
|
||||||
|
return sflash_disk_write(buff, sector, count);
|
||||||
|
} else {
|
||||||
|
os_fs_mount_t *mount_obj;
|
||||||
|
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||||
|
// optimization for the built-in sd card device
|
||||||
|
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||||
|
return sd_disk_write(buff, sector, count);
|
||||||
|
}
|
||||||
|
mount_obj->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(sector);
|
||||||
|
mount_obj->writeblocks[3] = mp_obj_new_bytearray_by_ref(count * 512, (void *)buff);
|
||||||
|
return mp_obj_get_int(mp_call_method_n_kw(2, 0, mount_obj->writeblocks));
|
||||||
|
}
|
||||||
|
// nothing mounted
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Miscellaneous Functions */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if _USE_IOCTL
|
||||||
|
DRESULT disk_ioctl (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||||
|
BYTE cmd, /* Control code */
|
||||||
|
void *buff /* Buffer to send/receive control data */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (pdrv == PD_FLASH) {
|
||||||
|
switch (cmd) {
|
||||||
|
case CTRL_SYNC:
|
||||||
|
return sflash_disk_flush();
|
||||||
|
case GET_SECTOR_COUNT:
|
||||||
|
*((DWORD*)buff) = SFLASH_SECTOR_COUNT;
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_SIZE:
|
||||||
|
*((DWORD*)buff) = SFLASH_SECTOR_SIZE;
|
||||||
|
return RES_OK;
|
||||||
|
case GET_BLOCK_SIZE:
|
||||||
|
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
os_fs_mount_t *mount_obj;
|
||||||
|
if ((mount_obj = osmount_find_by_volume(pdrv))) {
|
||||||
|
switch (cmd) {
|
||||||
|
case CTRL_SYNC:
|
||||||
|
if (mount_obj->sync[0] != MP_OBJ_NULL) {
|
||||||
|
mp_call_method_n_kw(0, 0, mount_obj->sync);
|
||||||
|
}
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_COUNT:
|
||||||
|
// optimization for the built-in sd card device
|
||||||
|
if (mount_obj->device == (mp_obj_t)&pybsd_obj) {
|
||||||
|
*((DWORD*)buff) = sd_disk_info.ulNofBlock * (sd_disk_info.ulBlockSize / 512);
|
||||||
|
} else {
|
||||||
|
*((DWORD*)buff) = mp_obj_get_int(mp_call_method_n_kw(0, 0, mount_obj->count));
|
||||||
|
}
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_SIZE:
|
||||||
|
*((DWORD*)buff) = SD_SECTOR_SIZE; // Sector size is fixed to 512 bytes, as with SD cards
|
||||||
|
return RES_OK;
|
||||||
|
case GET_BLOCK_SIZE:
|
||||||
|
*((DWORD*)buff) = 1; // high-level sector erase size in units of the block size
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// nothing mounted
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !_FS_READONLY && !_FS_NORTC
|
||||||
|
DWORD get_fattime (
|
||||||
|
void
|
||||||
|
)
|
||||||
|
{
|
||||||
|
timeutils_struct_time_t tm;
|
||||||
|
timeutils_seconds_since_2000_to_struct_time(pyb_rtc_get_seconds(), &tm);
|
||||||
|
|
||||||
|
return ((tm.tm_year - 1980) << 25) | ((tm.tm_mon) << 21) |
|
||||||
|
((tm.tm_mday) << 16) | ((tm.tm_hour) << 11) |
|
||||||
|
((tm.tm_min) << 5) | (tm.tm_sec >> 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -39,12 +39,11 @@
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "lib/oofatfs/ff.h"
|
|
||||||
#include "lib/oofatfs/diskio.h"
|
|
||||||
#include "hw_types.h"
|
#include "hw_types.h"
|
||||||
#include "hw_memmap.h"
|
#include "hw_memmap.h"
|
||||||
#include "hw_ints.h"
|
#include "hw_ints.h"
|
||||||
#include "rom_map.h"
|
#include "rom_map.h"
|
||||||
|
#include "diskio.h"
|
||||||
#include "sd_diskio.h"
|
#include "sd_diskio.h"
|
||||||
#include "sdhost.h"
|
#include "sdhost.h"
|
||||||
#include "pin.h"
|
#include "pin.h"
|
|
@ -1,12 +1,11 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include "std.h"
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "lib/oofatfs/ff.h"
|
|
||||||
#include "lib/oofatfs/diskio.h"
|
|
||||||
#include "simplelink.h"
|
#include "simplelink.h"
|
||||||
|
#include "diskio.h"
|
||||||
#include "sflash_diskio.h"
|
#include "sflash_diskio.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "modnetwork.h"
|
#include "modnetwork.h"
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "py/mpstate.h"
|
||||||
|
#include "lib/fatfs/ff.h"
|
||||||
|
#include "lib/fatfs/ffconf.h"
|
||||||
|
#include "lib/fatfs/diskio.h"
|
||||||
|
#include "moduos.h"
|
||||||
|
|
||||||
|
#if _FS_RPATH
|
||||||
|
extern BYTE ff_CurrVol;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATIC bool check_path(const TCHAR **path, const char *mount_point_str, mp_uint_t mount_point_len) {
|
||||||
|
if (strncmp(*path, mount_point_str, mount_point_len) == 0) {
|
||||||
|
if ((*path)[mount_point_len] == '/') {
|
||||||
|
*path += mount_point_len;
|
||||||
|
return true;
|
||||||
|
} else if ((*path)[mount_point_len] == '\0') {
|
||||||
|
*path = "/";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "path" is the path to lookup; will advance this pointer beyond the volume name.
|
||||||
|
// Returns logical drive number (-1 means invalid path).
|
||||||
|
int ff_get_ldnumber (const TCHAR **path) {
|
||||||
|
if (!(*path)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (**path != '/') {
|
||||||
|
#if _FS_RPATH
|
||||||
|
return ff_CurrVol;
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_path(path, "/flash", 6)) {
|
||||||
|
return PD_FLASH;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (mp_uint_t i = 0; i < MP_STATE_PORT(mount_obj_list).len; i++) {
|
||||||
|
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[i]));
|
||||||
|
if (check_path(path, mount_obj->path, mount_obj->pathlen)) {
|
||||||
|
return mount_obj->vol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ff_get_volname(BYTE vol, TCHAR **dest) {
|
||||||
|
if (vol == PD_FLASH) {
|
||||||
|
memcpy(*dest, "/flash", 6);
|
||||||
|
*dest += 6;
|
||||||
|
} else {
|
||||||
|
os_fs_mount_t *mount_obj;
|
||||||
|
if ((mount_obj = osmount_find_by_volume(vol))) {
|
||||||
|
memcpy(*dest, mount_obj->path, mount_obj->pathlen);
|
||||||
|
*dest += mount_obj->pathlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Sample code of OS dependent controls for FatFs */
|
||||||
|
/* (C)ChaN, 2014 */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if _FS_REENTRANT
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Create a Synchronization Object */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called in f_mount() function to create a new
|
||||||
|
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
|
||||||
|
/ the f_mount() function fails with FR_INT_ERR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_cre_syncobj ( /* !=0:Function succeeded, ==0:Could not create due to any error */
|
||||||
|
BYTE vol, /* Corresponding logical drive being processed */
|
||||||
|
_SYNC_t *sobj /* Pointer to return the created sync object */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
//
|
||||||
|
// *sobj = CreateMutex(NULL, FALSE, NULL); /* Win32 */
|
||||||
|
// ret = (int)(*sobj != INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
// *sobj = SyncObjects[vol]; /* uITRON (give a static created sync object) */
|
||||||
|
// ret = 1; /* The initial value of the semaphore must be 1. */
|
||||||
|
|
||||||
|
// *sobj = OSMutexCreate(0, &err); /* uC/OS-II */
|
||||||
|
// ret = (int)(err == OS_NO_ERR);
|
||||||
|
|
||||||
|
vSemaphoreCreateBinary( (*sobj) ); /* FreeRTOS */
|
||||||
|
ret = (int)(*sobj != NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Delete a Synchronization Object */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called in f_mount() function to delete a synchronization
|
||||||
|
/ object that created with ff_cre_syncobj function. When a 0 is returned,
|
||||||
|
/ the f_mount() function fails with FR_INT_ERR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_del_syncobj ( /* !=0:Function succeeded, ==0:Could not delete due to any error */
|
||||||
|
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
|
// ret = CloseHandle(sobj); /* Win32 */
|
||||||
|
|
||||||
|
// ret = 1; /* uITRON (nothing to do) */
|
||||||
|
|
||||||
|
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); /* uC/OS-II */
|
||||||
|
// ret = (int)(err == OS_NO_ERR);
|
||||||
|
|
||||||
|
vSemaphoreDelete(sobj); /* FreeRTOS */
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Request Grant to Access the Volume */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called on entering file functions to lock the volume.
|
||||||
|
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
||||||
|
_SYNC_t sobj /* Sync object to wait */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// ret = (int)(WaitForSingleObject(sobj, _FS_TIMEOUT) == WAIT_OBJECT_0); /* Win32 */
|
||||||
|
|
||||||
|
// ret = (int)(wai_sem(sobj) == E_OK); /* uITRON */
|
||||||
|
|
||||||
|
// OSMutexPend(sobj, _FS_TIMEOUT, &err)); /* uC/OS-II */
|
||||||
|
// ret = (int)(err == OS_NO_ERR);
|
||||||
|
|
||||||
|
ret = (int)(xSemaphoreTake(sobj, _FS_TIMEOUT) == pdTRUE); /* FreeRTOS */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Release Grant to Access the Volume */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called on leaving file functions to unlock the volume.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ff_rel_grant (
|
||||||
|
_SYNC_t sobj /* Sync object to be signaled */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// ReleaseMutex(sobj); /* Win32 */
|
||||||
|
|
||||||
|
// sig_sem(sobj); /* uITRON */
|
||||||
|
|
||||||
|
// OSMutexPost(sobj); /* uC/OS-II */
|
||||||
|
|
||||||
|
xSemaphoreGive(sobj); /* FreeRTOS */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Allocate a memory block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void* ff_memalloc ( /* Returns pointer to the allocated memory block */
|
||||||
|
UINT msize /* Number of bytes to allocate */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return pvPortMalloc(msize); /* Allocate a new memory block with POSIX API */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Free a memory block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void ff_memfree (
|
||||||
|
void* mblock /* Pointer to the memory block to free */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vPortFree(mblock); /* Discard the memory block with POSIX API */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -25,13 +25,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <ctype.h>
|
||||||
|
#include "std.h"
|
||||||
|
|
||||||
#include "py/runtime.h"
|
#include "py/mpstate.h"
|
||||||
#include "lib/timeutils/timeutils.h"
|
#include "py/obj.h"
|
||||||
#include "lib/oofatfs/ff.h"
|
|
||||||
#include "extmod/vfs.h"
|
|
||||||
#include "extmod/vfs_fat.h"
|
|
||||||
#include "inc/hw_types.h"
|
#include "inc/hw_types.h"
|
||||||
#include "inc/hw_ints.h"
|
#include "inc/hw_ints.h"
|
||||||
#include "inc/hw_memmap.h"
|
#include "inc/hw_memmap.h"
|
||||||
|
@ -45,9 +43,11 @@
|
||||||
#include "modusocket.h"
|
#include "modusocket.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "serverstask.h"
|
#include "serverstask.h"
|
||||||
|
#include "ff.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "socketfifo.h"
|
#include "socketfifo.h"
|
||||||
#include "updater.h"
|
#include "updater.h"
|
||||||
|
#include "timeutils.h"
|
||||||
#include "moduos.h"
|
#include "moduos.h"
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -115,7 +115,7 @@ typedef struct {
|
||||||
uint8_t *dBuffer;
|
uint8_t *dBuffer;
|
||||||
uint32_t ctimeout;
|
uint32_t ctimeout;
|
||||||
union {
|
union {
|
||||||
FF_DIR dp;
|
DIR dp;
|
||||||
FIL fp;
|
FIL fp;
|
||||||
};
|
};
|
||||||
int16_t lc_sd;
|
int16_t lc_sd;
|
||||||
|
@ -192,80 +192,6 @@ static const ftp_month_t ftp_month[] = { { "Jan" }, { "Feb" }, { "Mar" }, { "Apr
|
||||||
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
static SocketFifoElement_t ftp_fifoelements[FTP_SOCKETFIFO_ELEMENTS_MAX];
|
||||||
static FIFO_t ftp_socketfifo;
|
static FIFO_t ftp_socketfifo;
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
DEFINE VFS WRAPPER FUNCTIONS
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
// These wrapper functions are used so that the FTP server can access the
|
|
||||||
// mounted FATFS devices directly without going through the costly mp_vfs_XXX
|
|
||||||
// functions. The latter may raise exceptions and we would then need to wrap
|
|
||||||
// all calls in an nlr handler. The wrapper functions below assume that there
|
|
||||||
// are only FATFS filesystems mounted.
|
|
||||||
|
|
||||||
STATIC FATFS *lookup_path(const TCHAR **path) {
|
|
||||||
mp_vfs_mount_t *fs = mp_vfs_lookup_path(*path, path);
|
|
||||||
if (fs == MP_VFS_NONE || fs == MP_VFS_ROOT) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// here we assume that the mounted device is FATFS
|
|
||||||
return &((fs_user_mount_t*)MP_OBJ_TO_PTR(fs->obj))->fatfs;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC FRESULT f_open_helper(FIL *fp, const TCHAR *path, BYTE mode) {
|
|
||||||
FATFS *fs = lookup_path(&path);
|
|
||||||
if (fs == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
return f_open(fs, fp, path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC FRESULT f_opendir_helper(FF_DIR *dp, const TCHAR *path) {
|
|
||||||
FATFS *fs = lookup_path(&path);
|
|
||||||
if (fs == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
return f_opendir(fs, dp, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC FRESULT f_stat_helper(const TCHAR *path, FILINFO *fno) {
|
|
||||||
FATFS *fs = lookup_path(&path);
|
|
||||||
if (fs == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
return f_stat(fs, path, fno);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC FRESULT f_mkdir_helper(const TCHAR *path) {
|
|
||||||
FATFS *fs = lookup_path(&path);
|
|
||||||
if (fs == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
return f_mkdir(fs, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC FRESULT f_unlink_helper(const TCHAR *path) {
|
|
||||||
FATFS *fs = lookup_path(&path);
|
|
||||||
if (fs == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
return f_unlink(fs, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC FRESULT f_rename_helper(const TCHAR *path_old, const TCHAR *path_new) {
|
|
||||||
FATFS *fs_old = lookup_path(&path_old);
|
|
||||||
if (fs_old == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
FATFS *fs_new = lookup_path(&path_new);
|
|
||||||
if (fs_new == NULL) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
if (fs_old != fs_new) {
|
|
||||||
return FR_NO_PATH;
|
|
||||||
}
|
|
||||||
return f_rename(fs_new, path_old, path_new);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DECLARE PRIVATE FUNCTIONS
|
DECLARE PRIVATE FUNCTIONS
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -284,7 +210,7 @@ static void ftp_close_cmd_data (void);
|
||||||
static ftp_cmd_index_t ftp_pop_command (char **str);
|
static ftp_cmd_index_t ftp_pop_command (char **str);
|
||||||
static void ftp_pop_param (char **str, char *param);
|
static void ftp_pop_param (char **str, char *param);
|
||||||
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno);
|
||||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name);
|
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name);
|
||||||
static bool ftp_open_file (const char *path, int mode);
|
static bool ftp_open_file (const char *path, int mode);
|
||||||
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
static ftp_result_t ftp_read_file (char *filebuf, uint32_t desiredsize, uint32_t *actualsize);
|
||||||
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
static ftp_result_t ftp_write_file (char *filebuf, uint32_t size);
|
||||||
|
@ -334,7 +260,7 @@ void ftp_run (void) {
|
||||||
ftp_data.loggin.uservalid = false;
|
ftp_data.loggin.uservalid = false;
|
||||||
ftp_data.loggin.passvalid = false;
|
ftp_data.loggin.passvalid = false;
|
||||||
strcpy (ftp_path, "/");
|
strcpy (ftp_path, "/");
|
||||||
ftp_send_reply (220, "MicroPython FTP Server");
|
ftp_send_reply (220, "Micropython FTP Server");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,12 +424,12 @@ static void ftp_wait_for_enabled (void) {
|
||||||
|
|
||||||
static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||||
SlSockNonblocking_t nonBlockingOption;
|
SlSockNonblocking_t nonBlockingOption;
|
||||||
SlSockAddrIn_t sServerAddress;
|
sockaddr_in sServerAddress;
|
||||||
_i16 _sd;
|
_i16 _sd;
|
||||||
_i16 result;
|
_i16 result;
|
||||||
|
|
||||||
// Open a socket for ftp data listen
|
// Open a socket for ftp data listen
|
||||||
ASSERT ((*sd = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_IPPROTO_IP)) > 0);
|
ASSERT ((*sd = sl_Socket(AF_INET, SOCK_STREAM, IPPROTO_IP)) > 0);
|
||||||
_sd = *sd;
|
_sd = *sd;
|
||||||
|
|
||||||
if (_sd > 0) {
|
if (_sd > 0) {
|
||||||
|
@ -512,12 +438,12 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||||
|
|
||||||
// Enable non-blocking mode
|
// Enable non-blocking mode
|
||||||
nonBlockingOption.NonblockingEnabled = 1;
|
nonBlockingOption.NonblockingEnabled = 1;
|
||||||
ASSERT ((result = sl_SetSockOpt(_sd, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
ASSERT ((result = sl_SetSockOpt(_sd, SOL_SOCKET, SL_SO_NONBLOCKING, &nonBlockingOption, sizeof(nonBlockingOption))) == SL_SOC_OK);
|
||||||
|
|
||||||
// Bind the socket to a port number
|
// Bind the socket to a port number
|
||||||
sServerAddress.sin_family = SL_AF_INET;
|
sServerAddress.sin_family = AF_INET;
|
||||||
sServerAddress.sin_addr.s_addr = SL_INADDR_ANY;
|
sServerAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
sServerAddress.sin_port = sl_Htons(port);
|
sServerAddress.sin_port = htons(port);
|
||||||
|
|
||||||
ASSERT ((result |= sl_Bind(_sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress))) == SL_SOC_OK);
|
ASSERT ((result |= sl_Bind(_sd, (const SlSockAddr_t *)&sServerAddress, sizeof(sServerAddress))) == SL_SOC_OK);
|
||||||
|
|
||||||
|
@ -533,7 +459,7 @@ static bool ftp_create_listening_socket (_i16 *sd, _u16 port, _u8 backlog) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static ftp_result_t ftp_wait_for_connection (_i16 l_sd, _i16 *n_sd) {
|
static ftp_result_t ftp_wait_for_connection (_i16 l_sd, _i16 *n_sd) {
|
||||||
SlSockAddrIn_t sClientAddress;
|
sockaddr_in sClientAddress;
|
||||||
SlSocklen_t in_addrSize;
|
SlSocklen_t in_addrSize;
|
||||||
|
|
||||||
// accepts a connection from a TCP client, if there is any, otherwise returns SL_EAGAIN
|
// accepts a connection from a TCP client, if there is any, otherwise returns SL_EAGAIN
|
||||||
|
@ -678,6 +604,10 @@ static void ftp_process_cmd (void) {
|
||||||
ftp_result_t result;
|
ftp_result_t result;
|
||||||
FRESULT fres;
|
FRESULT fres;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
|
#if _USE_LFN
|
||||||
|
fno.lfname = NULL;
|
||||||
|
fno.lfsize = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
ftp_data.closechild = false;
|
ftp_data.closechild = false;
|
||||||
// also use the reply buffer to receive new commands
|
// also use the reply buffer to receive new commands
|
||||||
|
@ -704,7 +634,7 @@ static void ftp_process_cmd (void) {
|
||||||
fres = FR_NO_PATH;
|
fres = FR_NO_PATH;
|
||||||
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
ftp_pop_param (&bufptr, ftp_scratch_buffer);
|
||||||
ftp_open_child (ftp_path, ftp_scratch_buffer);
|
ftp_open_child (ftp_path, ftp_scratch_buffer);
|
||||||
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir_helper (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
if ((ftp_path[0] == '/' && ftp_path[1] == '\0') || ((fres = f_opendir (&ftp_data.dp, ftp_path)) == FR_OK)) {
|
||||||
if (fres == FR_OK) {
|
if (fres == FR_OK) {
|
||||||
f_closedir(&ftp_data.dp);
|
f_closedir(&ftp_data.dp);
|
||||||
}
|
}
|
||||||
|
@ -723,7 +653,7 @@ static void ftp_process_cmd (void) {
|
||||||
case E_FTP_CMD_SIZE:
|
case E_FTP_CMD_SIZE:
|
||||||
{
|
{
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||||
// send the size
|
// send the size
|
||||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u", (_u32)fno.fsize);
|
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u", (_u32)fno.fsize);
|
||||||
ftp_send_reply(213, (char *)ftp_data.dBuffer);
|
ftp_send_reply(213, (char *)ftp_data.dBuffer);
|
||||||
|
@ -735,7 +665,7 @@ static void ftp_process_cmd (void) {
|
||||||
break;
|
break;
|
||||||
case E_FTP_CMD_MDTM:
|
case E_FTP_CMD_MDTM:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||||
// send the last modified time
|
// send the last modified time
|
||||||
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u%02u%02u%02u%02u%02u",
|
snprintf((char *)ftp_data.dBuffer, FTP_BUFFER_SIZE, "%u%02u%02u%02u%02u%02u",
|
||||||
1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f,
|
1980 + ((fno.fdate >> 9) & 0x7f), (fno.fdate >> 5) & 0x0f,
|
||||||
|
@ -843,7 +773,7 @@ static void ftp_process_cmd (void) {
|
||||||
case E_FTP_CMD_DELE:
|
case E_FTP_CMD_DELE:
|
||||||
case E_FTP_CMD_RMD:
|
case E_FTP_CMD_RMD:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_unlink_helper(ftp_path)) {
|
if (FR_OK == f_unlink(ftp_path)) {
|
||||||
ftp_send_reply(250, NULL);
|
ftp_send_reply(250, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -852,7 +782,7 @@ static void ftp_process_cmd (void) {
|
||||||
break;
|
break;
|
||||||
case E_FTP_CMD_MKD:
|
case E_FTP_CMD_MKD:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_mkdir_helper(ftp_path)) {
|
if (FR_OK == f_mkdir(ftp_path)) {
|
||||||
ftp_send_reply(250, NULL);
|
ftp_send_reply(250, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -861,7 +791,7 @@ static void ftp_process_cmd (void) {
|
||||||
break;
|
break;
|
||||||
case E_FTP_CMD_RNFR:
|
case E_FTP_CMD_RNFR:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
if (FR_OK == f_stat_helper(ftp_path, &fno)) {
|
if (FR_OK == f_stat (ftp_path, &fno)) {
|
||||||
ftp_send_reply(350, NULL);
|
ftp_send_reply(350, NULL);
|
||||||
// save the current path
|
// save the current path
|
||||||
strcpy ((char *)ftp_data.dBuffer, ftp_path);
|
strcpy ((char *)ftp_data.dBuffer, ftp_path);
|
||||||
|
@ -873,7 +803,7 @@ static void ftp_process_cmd (void) {
|
||||||
case E_FTP_CMD_RNTO:
|
case E_FTP_CMD_RNTO:
|
||||||
ftp_get_param_and_open_child (&bufptr);
|
ftp_get_param_and_open_child (&bufptr);
|
||||||
// old path was saved in the data buffer
|
// old path was saved in the data buffer
|
||||||
if (FR_OK == (fres = f_rename_helper((char *)ftp_data.dBuffer, ftp_path))) {
|
if (FR_OK == (fres = f_rename ((char *)ftp_data.dBuffer, ftp_path))) {
|
||||||
ftp_send_reply(250, NULL);
|
ftp_send_reply(250, NULL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -930,13 +860,6 @@ static void ftp_close_cmd_data (void) {
|
||||||
ftp_close_filesystem_on_error ();
|
ftp_close_filesystem_on_error ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stoupper (char *str) {
|
|
||||||
while (str && *str != '\0') {
|
|
||||||
*str = (char)unichar_toupper((int)(*str));
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ftp_cmd_index_t ftp_pop_command (char **str) {
|
static ftp_cmd_index_t ftp_pop_command (char **str) {
|
||||||
char _cmd[FTP_CMD_SIZE_MAX];
|
char _cmd[FTP_CMD_SIZE_MAX];
|
||||||
ftp_pop_param (str, _cmd);
|
ftp_pop_param (str, _cmd);
|
||||||
|
@ -975,16 +898,24 @@ static int ftp_print_eplf_item (char *dest, uint32_t destsize, FILINFO *fno) {
|
||||||
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
if (FTP_UNIX_SECONDS_180_DAYS < tseconds - fseconds) {
|
||||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %5u %s\r\n",
|
||||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||||
|
#if _USE_LFN
|
||||||
|
1980 + ((fno->fdate >> 9) & 0x7f), *fno->lfname ? fno->lfname : fno->fname);
|
||||||
|
#else
|
||||||
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
|
1980 + ((fno->fdate >> 9) & 0x7f), fno->fname);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
|
return snprintf(dest, destsize, "%srw-rw-r-- 1 root root %9u %s %2u %02u:%02u %s\r\n",
|
||||||
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
type, (_u32)fno->fsize, ftp_month[mindex].month, day,
|
||||||
|
#if _USE_LFN
|
||||||
|
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, *fno->lfname ? fno->lfname : fno->fname);
|
||||||
|
#else
|
||||||
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
|
(fno->ftime >> 11) & 0x1f, (fno->ftime >> 5) & 0x3f, fno->fname);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name) {
|
static int ftp_print_eplf_drive (char *dest, uint32_t destsize, char *name) {
|
||||||
timeutils_struct_time_t tm;
|
timeutils_struct_time_t tm;
|
||||||
uint32_t tseconds;
|
uint32_t tseconds;
|
||||||
char *type = "d";
|
char *type = "d";
|
||||||
|
@ -1003,7 +934,7 @@ static int ftp_print_eplf_drive (char *dest, uint32_t destsize, const char *name
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ftp_open_file (const char *path, int mode) {
|
static bool ftp_open_file (const char *path, int mode) {
|
||||||
FRESULT res = f_open_helper(&ftp_data.fp, path, mode);
|
FRESULT res = f_open(&ftp_data.fp, path, mode);
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1045,7 +976,7 @@ static ftp_result_t ftp_open_dir_for_listing (const char *path) {
|
||||||
ftp_data.listroot = true;
|
ftp_data.listroot = true;
|
||||||
} else {
|
} else {
|
||||||
FRESULT res;
|
FRESULT res;
|
||||||
res = f_opendir_helper(&ftp_data.dp, path); /* Open the directory */
|
res = f_opendir(&ftp_data.dp, path); /* Open the directory */
|
||||||
if (res != FR_OK) {
|
if (res != FR_OK) {
|
||||||
return E_FTP_RESULT_FAILED;
|
return E_FTP_RESULT_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -1062,6 +993,9 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||||
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
ftp_result_t result = E_FTP_RESULT_CONTINUE;
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
#if _USE_LFN
|
#if _USE_LFN
|
||||||
|
fno.lfname = mem_Malloc(_MAX_LFN);
|
||||||
|
fno.lfsize = _MAX_LFN;
|
||||||
|
|
||||||
// read up to 2 directory items
|
// read up to 2 directory items
|
||||||
while (listcount < 2) {
|
while (listcount < 2) {
|
||||||
#else
|
#else
|
||||||
|
@ -1070,20 +1004,17 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||||
#endif
|
#endif
|
||||||
if (ftp_data.listroot) {
|
if (ftp_data.listroot) {
|
||||||
// root directory "hack"
|
// root directory "hack"
|
||||||
mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table);
|
if (0 == ftp_data.volcount) {
|
||||||
int i = ftp_data.volcount;
|
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), "flash");
|
||||||
while (vfs != NULL && i != 0) {
|
} else if (ftp_data.volcount <= MP_STATE_PORT(mount_obj_list).len) {
|
||||||
vfs = vfs->next;
|
os_fs_mount_t *mount_obj = ((os_fs_mount_t *)(MP_STATE_PORT(mount_obj_list).items[(ftp_data.volcount - 1)]));
|
||||||
i -= 1;
|
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), (char *)&mount_obj->path[1]);
|
||||||
}
|
} else {
|
||||||
if (vfs == NULL) {
|
|
||||||
if (!next) {
|
if (!next) {
|
||||||
// no volume found this time, we are done
|
// no volume found this time, we are done
|
||||||
ftp_data.volcount = 0;
|
ftp_data.volcount = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
next += ftp_print_eplf_drive((list + next), (maxlistsize - next), vfs->str + 1);
|
|
||||||
}
|
}
|
||||||
ftp_data.volcount++;
|
ftp_data.volcount++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1105,6 +1036,9 @@ static ftp_result_t ftp_list_dir (char *list, uint32_t maxlistsize, uint32_t *li
|
||||||
ftp_close_files();
|
ftp_close_files();
|
||||||
}
|
}
|
||||||
*listsize = next;
|
*listsize = next;
|
||||||
|
#if _USE_LFN
|
||||||
|
mem_Free(fno.lfname);
|
||||||
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -23,8 +23,9 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_CC3200_FTP_FTP_H
|
|
||||||
#define MICROPY_INCLUDED_CC3200_FTP_FTP_H
|
#ifndef FTP_H_
|
||||||
|
#define FTP_H_
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DECLARE EXPORTED FUNCTIONS
|
DECLARE EXPORTED FUNCTIONS
|
||||||
|
@ -35,4 +36,4 @@ extern void ftp_enable (void);
|
||||||
extern void ftp_disable (void);
|
extern void ftp_disable (void);
|
||||||
extern void ftp_reset (void);
|
extern void ftp_reset (void);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_CC3200_FTP_FTP_H
|
#endif /* FTP_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -23,8 +23,10 @@
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_CC3200_FTP_UPDATER_H
|
|
||||||
#define MICROPY_INCLUDED_CC3200_FTP_UPDATER_H
|
|
||||||
|
#ifndef UPDATER_H_
|
||||||
|
#define UPDATER_H_
|
||||||
|
|
||||||
extern void updater_pre_init (void);
|
extern void updater_pre_init (void);
|
||||||
extern bool updater_check_path (void *path);
|
extern bool updater_check_path (void *path);
|
||||||
|
@ -33,4 +35,4 @@ extern bool updater_write (uint8_t *buf, uint32_t len);
|
||||||
extern void updater_finnish (void);
|
extern void updater_finnish (void);
|
||||||
extern bool updater_verify (uint8_t *rbuff, uint8_t *hasbuff);
|
extern bool updater_verify (uint8_t *rbuff, uint8_t *hasbuff);
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_CC3200_FTP_UPDATER_H
|
#endif /* UPDATER_H_ */
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "py/mpstate.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
|
@ -107,19 +108,6 @@ mp_uint_t mp_hal_ticks_ms(void) {
|
||||||
return HAL_tickCount;
|
return HAL_tickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The SysTick timer counts down at HAL_FCPU_HZ, so we can use that knowledge
|
|
||||||
// to grab a microsecond counter.
|
|
||||||
mp_uint_t mp_hal_ticks_us(void) {
|
|
||||||
mp_uint_t irq_state = disable_irq();
|
|
||||||
uint32_t counter = SysTickValueGet();
|
|
||||||
uint32_t milliseconds = mp_hal_ticks_ms();
|
|
||||||
enable_irq(irq_state);
|
|
||||||
|
|
||||||
uint32_t load = SysTickPeriodGet();
|
|
||||||
counter = load - counter; // Convert from decrementing to incrementing
|
|
||||||
return (milliseconds * 1000) + ((counter * 1000) / load);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mp_hal_delay_ms(mp_uint_t delay) {
|
void mp_hal_delay_ms(mp_uint_t delay) {
|
||||||
// only if we are not within interrupt context and interrupts are enabled
|
// only if we are not within interrupt context and interrupts are enabled
|
||||||
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
if ((HAL_NVIC_INT_CTRL_REG & HAL_VECTACTIVE_MASK) == 0 && query_irq() == IRQ_STATE_ENABLED) {
|
||||||
|
@ -142,13 +130,21 @@ void mp_hal_delay_ms(mp_uint_t delay) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NORETURN void mp_hal_raise(int errno) {
|
||||||
|
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, mp_obj_new_int(errno)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mp_hal_set_interrupt_char (int c) {
|
||||||
|
mpexception_set_interrupt_char (c);
|
||||||
|
}
|
||||||
|
|
||||||
void mp_hal_stdout_tx_str(const char *str) {
|
void mp_hal_stdout_tx_str(const char *str) {
|
||||||
mp_hal_stdout_tx_strn(str, strlen(str));
|
mp_hal_stdout_tx_strn(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
||||||
if (MP_STATE_PORT(os_term_dup_obj)) {
|
if (MP_STATE_PORT(os_term_dup_obj)) {
|
||||||
if (mp_obj_is_type(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) {
|
if (MP_OBJ_IS_TYPE(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) {
|
||||||
uart_tx_strn(MP_STATE_PORT(os_term_dup_obj)->stream_o, str, len);
|
uart_tx_strn(MP_STATE_PORT(os_term_dup_obj)->stream_o, str, len);
|
||||||
} else {
|
} else {
|
||||||
MP_STATE_PORT(os_term_dup_obj)->write[2] = mp_obj_new_str_of_type(&mp_type_str, (const byte *)str, len);
|
MP_STATE_PORT(os_term_dup_obj)->write[2] = mp_obj_new_str_of_type(&mp_type_str, (const byte *)str, len);
|
||||||
|
@ -184,7 +180,7 @@ int mp_hal_stdin_rx_chr(void) {
|
||||||
if (telnet_rx_any()) {
|
if (telnet_rx_any()) {
|
||||||
return telnet_rx_char();
|
return telnet_rx_char();
|
||||||
} else if (MP_STATE_PORT(os_term_dup_obj)) { // then the stdio_dup
|
} else if (MP_STATE_PORT(os_term_dup_obj)) { // then the stdio_dup
|
||||||
if (mp_obj_is_type(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) {
|
if (MP_OBJ_IS_TYPE(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) {
|
||||||
if (uart_rx_any(MP_STATE_PORT(os_term_dup_obj)->stream_o)) {
|
if (uart_rx_any(MP_STATE_PORT(os_term_dup_obj)->stream_o)) {
|
||||||
return uart_rx_char(MP_STATE_PORT(os_term_dup_obj)->stream_o);
|
return uart_rx_char(MP_STATE_PORT(os_term_dup_obj)->stream_o);
|
||||||
}
|
}
|
||||||
|
@ -219,3 +215,4 @@ static void hal_TickInit (void) {
|
||||||
MAP_SysTickEnable();
|
MAP_SysTickEnable();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
|
@ -24,12 +24,12 @@
|
||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef CC3200_LAUNCHXL_HAL_CC3200_HAL_H_
|
||||||
|
#define CC3200_LAUNCHXL_HAL_CC3200_HAL_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "hal/utils.h"
|
|
||||||
#include "hal/systick.h"
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
DEFINE CONSTANTS
|
DEFINE CONSTANTS
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -62,8 +62,7 @@
|
||||||
extern void HAL_SystemInit (void);
|
extern void HAL_SystemInit (void);
|
||||||
extern void HAL_SystemDeInit (void);
|
extern void HAL_SystemDeInit (void);
|
||||||
extern void HAL_IncrementTick(void);
|
extern void HAL_IncrementTick(void);
|
||||||
|
extern NORETURN void mp_hal_raise(int errno);
|
||||||
extern void mp_hal_set_interrupt_char (int c);
|
extern void mp_hal_set_interrupt_char (int c);
|
||||||
|
|
||||||
#define mp_hal_stdio_poll(poll_flags) (0) // not implemented
|
#endif /* CC3200_LAUNCHXL_HAL_CC3200_HAL_H_ */
|
||||||
#define mp_hal_delay_us(usec) UtilsDelay(UTILS_DELAY_US_TO_COUNT(usec))
|
|
||||||
#define mp_hal_ticks_cpu() (SysTickPeriodGet() - SysTickValueGet())
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of the MicroPython project, http://micropython.org/
|
* This file is part of the Micro Python project, http://micropython.org/
|
||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue